selinux导致主从同步失败时,表现为io线程中断、连接拒绝等隐性错误;需用getenforce确认模式,ausearch定位avc拦截点,再通过setsebool开启mysqld_can_network_connect、semanage修正relay log上下文或端口类型来精准修复。

数据库同步失败若由 SELinux 引发,通常不报明确错误,只表现为主从连接中断、IO线程卡住(Slave_IO_Running: No)、复制延迟飙升,或错误日志中反复出现 Permission denied、Connection refused、Can't connect to MySQL server 等提示——但网络和账号权限本身无误。核心思路是:先确认 SELinux 是否在拦,再定位它拦了哪一环(端口?socket?网络连接?文件读写?),最后精准修复上下文或布尔值,而非直接禁用。
确认 SELinux 是否为根因
运行以下命令快速验证:
-
查当前模式:
getenforce—— 若返回Enforcing,说明策略正在生效;若为Permissive或Disabled,基本可排除 SELinux -
临时宽容验证:
sudo setenforce 0,然后立即重启 MySQL 并检查同步状态:systemctl restart mysqld && mysql -e "SHOW SLAVE STATUS\G" | grep -E "(IO|SQL)_Running"—— 若此时恢复为Yes,基本锁定 SELinux 拦截 -
切回强制模式:
sudo setenforce 1,避免审计日志丢失关键线索
查拒绝日志,定位同步被拦的具体环节
同步失败常涉及三类 SELinux 拦截点,需针对性查日志:
-
查网络连接拒绝(主从通信):
ausearch -m avc -ts recent | grep -i -E "(connect|name_connect|mysql|mysqld)"—— 关注tclass=socket、perm=name_connect类型的 AVC 记录 -
查端口绑定/访问拒绝(如从库连主库 3306):
ausearch -m avc -c mysqld | audit2why——audit2why会指出是否缺mysqld_can_network_connect布尔值,或目标端口未标记为mysql_port_t -
查数据目录或 relay log 文件拒绝(IO线程写中继日志失败):
ausearch -m avc -c mysqld | grep -i "relay\|log\|data"—— 若发现tcontext=var_log_t或default_t而非mysqld_db_t,说明文件上下文错配
修复三类高频同步拦截场景
90% 的同步失败对应以下三种修复方式,按需选用:
-
开启网络连接布尔值:MySQL 主从需主动发起连接,默认被禁。执行
sudo setsebool -P mysqld_can_network_connect on(-P表示永久生效) -
修正 relay log 目录上下文:若 relay log 存放在非默认路径(如
/data/mysql/relay),先查标签:ls -Zd /data/mysql/relay;若非mysqld_db_t,则添加规则并恢复:sudo semanage fcontext -a -t mysqld_db_t "/data/mysql/relay(/.*)?"; sudo restorecon -Rv /data/mysql/relay -
校准主库监听端口类型:若主库使用非标端口(如 3307),需将其加入 MySQL 端口类型:
sudo semanage port -l | grep mysql_port_t查当前允许端口;若 3307 不在列,执行sudo semanage port -a -t mysql_port_t -p tcp 3307
补充验证与收尾
修复后务必执行:
- 重启 MySQL:
systemctl restart mysqld - 重置并启动同步:
mysql -e "STOP SLAVE; RESET SLAVE; START SLAVE;" - 持续观察 2–5 分钟:
mysql -e "SHOW SLAVE STATUS\G" | grep -E "(Seconds_Behind_Master|IO|SQL)_Running",确认无延迟且线程为Yes - 复查审计日志是否仍有新 AVC 拒绝:
ausearch -m avc -c mysqld -ts today—— 零输出即表示拦截已解除











