Slave_IO_Running持续Connecting或No,主因是slave_net_timeout超时断连而非连接失败;该参数控制I/O线程读取binlog的等待时长,默认60秒,空闲期稍长即触发断连重试,需结合GTID启用AUTO_POSITION=1、调优tcp_keepalive及重试参数协同解决。

Slave_IO_Running 一直 Connecting 或 No,但 telnet 通、账号权限正常
这大概率不是连不上,而是连上后被 slave_net_timeout 主动断开再重试。它只看“有没有新 binlog 数据”,不看 TCP 连接是否还活着。主库写入空闲期稍长(比如夜间),IO 线程就会超时断开,日志里反复出现 Connecting 状态,Last_IO_Error 可能为空或只提示 “The slave I/O thread stops because a fatal error is encountered…”。
检查当前值:SHOW VARIABLES LIKE 'slave_net_timeout';
临时调大(例如设为 7200):SET GLOBAL slave_net_timeout = 7200;
永久生效需写入从库 my.cnf 的 [mysqld] 段:slave_net_timeout = 7200
改完必须执行:STOP SLAVE; START SLAVE;,否则不生效
GTID 模式下 IO 线程失败后根本不重试
MySQL 默认行为就是“连一次,失败就停”。Slave_IO_Running: No 且 Last_IO_Error 是 “error connecting to master”,说明压根没触发重连逻辑——根本没启用自动重连机制。
- 确认是否启用了 GTID:
SELECT @@gtid_mode;必须是ON - 检查
CHANGE MASTER TO是否明确包含AUTO_POSITION = 1(不是 0,也不能省略) - 执行
SHOW SLAVE STATUS\G,看Auto_Position字段是否为1;若为0,调再小的slave_net_timeout也白搭
重连延迟高、恢复慢,或频繁断连
slave_net_timeout 不是重连间隔,只是“读超时阈值”:它决定 IO 线程等多久没收到数据(binlog 或心跳)就断开连接,之后才可能触发重连——但重连是否发生、隔多久重、重几次,由 MASTER_CONNECT_RETRY、MASTER_RETRY_COUNT 和 MASTER_HEARTBEAT_PERIOD 共同控制。
-
slave_net_timeout默认值在 5.7.7+ 是 60 秒,老版本是 3600 秒。设太大(如 3600)会让抖动后延迟数分钟才感知断连;设太小(如 5 或 10)又会导致公网偶发丢包就频繁断连 - 跨机房或云上 VPC 建议设为 30,局域网可设 60
- 必须配合
MASTER_HEARTBEAT_PERIOD(建议设为slave_net_timeout / 2),否则心跳发得太晚,超时仍会触发断连 -
MASTER_CONNECT_RETRY控制每次重试前等待秒数,默认 60;可通过CHANGE MASTER TO MASTER_CONNECT_RETRY = 10缩短 - 修改后需执行:
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;才生效,SET GLOBAL不会重建连接
网络层干扰导致的假断连:别忽略 tcp_keepalive 系统参数
MySQL 自身不控制底层 TCP keepalive 行为。当中间有防火墙、NAT 设备或云厂商负载均衡时,它们常默认 300 秒无流量就清空连接表项。此时即使 MySQL 的 slave_net_timeout 设得再大也没用——连接早被中间设备掐断了。
- 建议调低内核参数:
net.ipv4.tcp_keepalive_time = 600 - 配套调整:
net.ipv4.tcp_keepalive_intvl = 60,net.ipv4.tcp_keepalive_probes = 3 - 这些参数需在主从两端同时设置,仅改 MySQL 配置治标不治本
AUTO_POSITION = 1 没配全,或者 tcp_keepalive 被忽略——这两处不查,光调 slave_net_timeout 就像修水管只拧水龙头。


















