MySQL从库IO线程卡在Connecting状态,主因是防火墙/安全组空闲超时与slave_net_timeout不匹配,需同步调整二者并重启复制线程。

从库 Slave_IO_Running 显示 Connecting 但网络连通性正常
这大概率不是防火墙彻底拦死,而是连接建立后被策略主动中断。常见于防火墙或云安全组设置了空闲连接超时(如 60 秒、300 秒),而 MySQL 默认 slave_net_timeout = 3600,但主库若长时间无写入,IO 线程会静默等待——此时防火墙先断掉 TCP 连接,从库再尝试重连就卡在 Connecting 状态。
- 先验证是否真被拦截:在从库执行
telnet 主库IP 3306,能通不代表稳;再持续观察 5 分钟,看连接是否中途断开 - 检查主库所在节点的防火墙实际规则:
iptables -L INPUT -n --line-numbers或ufw status verbose - 重点确认是否有类似
REJECT tcp dpt:3306的显式拒绝项,或ctstate INVALID类规则误判长连接 - 云环境(如阿里云、AWS)务必检查安全组的“入方向”规则,且注意规则顺序——靠前的拒绝规则会生效
修复时必须同步调整 slave_net_timeout 和 master_heartbeat_period
只改防火墙不调参数,问题会复发;只调参数不改防火墙,连接仍会被掐断。两者必须配合。
-
slave_net_timeout要设为防火墙空闲超时值的 2–3 倍(例如防火墙超时 300 秒,则设SET GLOBAL slave_net_timeout = 900) -
master_heartbeat_period必须在CHANGE MASTER TO时显式设置,且单位是秒(小数合法,如10.0),整数会报错;建议设为slave_net_timeout的 1/3~1/2 - 改完必须执行
STOP SLAVE; START SLAVE;,仅RESET SLAVE不生效 - 永久生效需写入从库
my.cnf的[mysqld]段:slave_net_timeout = 900
排查 Last_IO_Error 里 “reconnecting to master” 的真实原因
这个错误常被当成网络问题,但实际根因可能是防火墙策略在重连瞬间生效,导致连接被拒绝,日志只记录表层现象。
- 在从库手动模拟重连:
mysql -h 主库IP -u 复制用户 -p -e "SELECT 1",重复执行多次,观察是否偶发失败 - 查主库当前连接数:
SHOW STATUS LIKE 'Threads_connected';,对比max_connections,确认没被打满 - 翻主库错误日志(
error.log),搜索关键词Access denied、Too many connections、Connection reset,尤其关注时间戳是否与从库报错时刻吻合 - 若发现 SELinux 启用,检查
ausearch -m avc -ts recent是否有mysql_t相关拒绝记录
防火墙放行后仍断开,要检查复制用户的 host 权限
防火墙放开 3306 端口,不代表 MySQL 允许该 IP 连接——host 字段匹配失败也会表现为连接中断,且错误日志里可能只显示模糊的认证失败。
- 在主库执行:
SELECT user, host FROM mysql.user WHERE user = 'repl_user';,确认返回的host是具体 IP、%还是域名 - 若为域名,检查从库 DNS 解析是否稳定;若为
%,确认主库未启用skip-name-resolve导致反向解析失败 - 临时测试可改为
'repl_user'@'从库IP'并FLUSH PRIVILEGES;,排除 wildcard 匹配问题 - 避免使用
'repl_user'@'localhost'——这只能本机连,对从库无效
slave_net_timeout 和防火墙空闲超时的实际值,别凭经验硬套。


















