slave_net_timeout是读空闲超时阈值,非重连间隔;设30~60秒合理,修改后须执行stop slave io_thread; start slave io_thread;才生效,gtid模式下还需auto_position=1且配master_heartbeat_period。

slave_net_timeout 设得太小或太大都会让复制在抖动时表现异常——它不是“重连间隔”,而是从库判断“主库是不是挂了”的读空闲阈值。默认 3600 秒(1 小时)在公网或跨机房场景下根本不可用,设成 30~60 秒才合理。
为什么 slave_net_timeout 改了却没效果?
常见现象:SET GLOBAL slave_net_timeout = 30 后 SHOW SLAVE STATUS\G 里 Slave_IO_Running 仍是 Connecting 或 No,且 Last_IO_Error 为空。
- 必须执行
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;,只改变量不重启线程不生效 - GTID 模式下,
AUTO_POSITION = 1必须显式写在CHANGE MASTER TO语句里,否则即使参数调对,IO 线程失败后也不会自动重试 - MySQL 5.6 及更早版本不支持动态修改该参数,必须写入
my.cnf并重启mysqld
MASTER_HEARTBEAT_PERIOD 怎么配才真正起作用?
MySQL 5.7+ 的心跳是主库主动发的 HEARTBEAT event,不是 TCP keepalive,也不由从库控制。它只在 IO 线程已连接、但主库无新 binlog 时维持连接活性。
- 必须在从库执行
CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD = 15;(建议值为slave_net_timeout / 2,且至少比它小 10 秒) - 主库
binlog_format推荐设为ROW,STATEMENT模式下某些场景会跳过心跳 - 心跳 event 不写入 relay log,不影响 SQL 线程,仅用于避免
slave_net_timeout触发误断连
中间设备清空连接表,MySQL 配置再好也没用
云厂商 LB、NAT 网关、防火墙常默认 300 秒无流量就踢掉 TCP 连接。此时 slave_net_timeout 设成 3600 也白搭——连接早被掐断,MySQL 层根本收不到超时信号。
- 主从两端都要调系统级
tcp_keepalive参数:net.ipv4.tcp_keepalive_time = 600、net.ipv4.tcp_keepalive_intvl = 60、net.ipv4.tcp_keepalive_probes = 3 - 验证是否生效:
ss -i查看连接的keepalive字段,或用tcpdump抓包确认 keepalive 包是否发出 - 别漏掉
skip_name_resolve = ON:DNS 解析卡顿 >5 秒会直接导致 GCS 或复制心跳中断(尤其在 MGR 场景下)
Seconds_Behind_Master 短暂飙高是正常现象;但如果你看到 Slave_IO_Running 长期卡在 Connecting,那大概率是 MASTER_CONNECT_RETRY 和 MASTER_RETRY_COUNT 没配,或者主库 binlog 已被清理导致重连后无法定位位置——这时候光调 slave_net_timeout 解决不了问题。











