gtid模式下自动重连需同时启用gtid和auto_position=1,否则io线程失败后不重试;slave_net_timeout仅控制读超时,重连行为由master_connect_retry、master_retry_count和master_heartbeat_period共同决定。

主从频繁重连不是参数调得不对,而是根本没启用自动重连机制——GTID + AUTO_POSITION=1 缺一不可。
为什么 SHOW SLAVE STATUS 显示 Slave_IO_Running: No 且 Last_IO_Error 是 “error connecting to master”
这说明 IO 线程压根没尝试重连,只连了一次就停了。MySQL 默认行为就是如此:不启用 GTID、不设 AUTO_POSITION=1,IO 线程失败后不会自动重试。
- 检查是否启用了 GTID:
SELECT @@gtid_mode;必须是ON - 确认 CHANGE MASTER TO 是否包含
AUTO_POSITION = 1(不是0或省略) - 执行
SHOW SLAVE STATUS\G,看Auto_Position字段是否为1 - 如果
Auto_Position: 0,即使slave_net_timeout设再小也白搭
slave_net_timeout 不是重连间隔,而是“读超时阈值”
它只决定 IO 线程等多久没收到数据(binlog 或心跳)就断开当前连接,然后才触发重连逻辑——但重连是否发生、隔多久重、重几次,由其他参数控制。
-
slave_net_timeout默认值在 5.7.7+ 是60,老版本是3600;设太大(如 300)会让网络抖动后延迟数分钟才感知断连 - 跨机房或云上 VPC 建议设为
30,局域网可设60;切忌设成5或10,公网偶发丢包就会频繁断连 - 必须配合
MASTER_HEARTBEAT_PERIOD(建议设为slave_net_timeout / 2),否则心跳发得太晚,超时仍会触发 - 修改后需执行
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;才生效,SET GLOBAL不会重建连接
重连行为真正由这三个参数联合控制
仅调 slave_net_timeout 解决不了“连不上就躺平”的问题,得看完整链路:
-
MASTER_CONNECT_RETRY:断连后等待几秒再发起下一次重连,默认60;可通过CHANGE MASTER TO MASTER_CONNECT_RETRY = 10缩短 -
MASTER_RETRY_COUNT:总共重试多少次,默认是86400(即 60 天),实际意义不大;设为0表示无限重试(慎用,可能掩盖真实故障) -
MASTER_HEARTBEAT_PERIOD:主库发送心跳的间隔,必须小于slave_net_timeout,否则 IO 线程永远等不到心跳,直接超时断开 - 查看当前值:
SHOW SLAVE STATUS\G中的Master_Retry_Count、Heartbeat字段,以及SELECT @@global.slave_net_timeout;
网络抖动场景下必须验证的三个状态点
别只盯着 Slave_IO_Running: Yes,它正常不代表同步健康:
-
Seconds_Behind_Master为NULL→ IO 线程已断,不是“慢”,是“失联” -
Read_Master_Log_Pos长时间不变,但Exec_Master_Log_Pos在涨 → IO 线程卡在读网络,可能是防火墙静默丢包或中间设备限速 -
Relay_Log_Space持续上涨,Exec_Master_Log_Pos不动 → SQL 线程积压,和网络无关,先查大事务或缺失索引 - 真要验证网络层是否可靠,用
tcpdump -i any port 3306 and host [master_ip]抓包,看是否有大量重传或 RST
最容易被忽略的是:GTID 开启后,AUTO_POSITION=1 必须显式写在 CHANGE MASTER TO 里,且 START SLAVE 前不能漏掉。很多线上实例配置文件里写了,但实际执行时忘了加这一项,导致所有网络参数都成了摆设。











