slave_net_timeout 设置不合理是主从连接频繁断开的直接原因,它控制从库IO线程空闲时主动断连的时间,而非网络故障检测;默认值在多数生产场景下不适用,需结合网络环境、心跳与重试参数协同调整,并启用TCP keepalive及正确配置GTID自动定位。

slave_net_timeout 设得不合理,是主从连接频繁断开的直接原因。它不是“网络不通”的表现,而是从库 IO 线程在空闲时主动断连——只要没收到新 binlog 数据,等够设定秒数就断,然后才考虑重试。默认值(5.7.7+ 是 60,老版本是 3600)在多数生产场景下都不适配。
为什么 slave_net_timeout 一设小就频繁 Connecting?
IO 线程只看“有没有数据可读”,不检测 TCP 连接是否存活。主库写入低峰期(比如夜间或批量任务间隙),哪怕网络完全正常,从库也会因收不到数据,在 slave_net_timeout 秒后主动断开当前连接,进入重连流程。
- 设为 10 或 15:主库空闲 12 秒就会断,重连握手压力大,日志里反复出现
Connecting状态 - 设为 3600(旧默认):网络抖动后要等 1 小时才感知断连,复制延迟飙升且无告警
- 局域网稳定环境建议设为
60;跨机房或云上 VPC 建议设为30,兼顾灵敏与稳定 - 改完必须执行
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;,仅SET GLOBAL不生效
为什么开了 GTID 还是不自动重连?
GTID 模式本身不等于自动重连。真正触发重试的是 AUTO_POSITION = 1 这个显式开关,缺了它,IO 线程失败后直接停在 Slave_IO_Running: No。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 确认 GTID 已启用:
SELECT @@gtid_mode;返回ON - 检查
SHOW SLAVE STATUS\G中Auto_Position字段是否为1;若为0,说明CHANGE MASTER TO里漏了AUTO_POSITION = 1 - 传统 file/pos 模式(用
MASTER_LOG_FILE+MASTER_LOG_POS)下,无论怎么调参都不会自动重试
slave_net_timeout 和心跳、重试参数怎么配才不打架?
slave_net_timeout 控制“读超时”,MASTER_HEARTBEAT_PERIOD 控制主库发心跳的节奏,MASTER_CONNECT_RETRY 控制从库重试前的等待间隔——三者不匹配,就会反复断连。
-
MASTER_HEARTBEAT_PERIOD(单位毫秒)必须设为slave_net_timeout / 2,例如slave_net_timeout = 30,则设MASTER_HEARTBEAT_PERIOD = 15000;否则心跳太晚,仍会触发超时 -
MASTER_CONNECT_RETRY默认 60 秒,可调小(如10)加快重试频率:CHANGE MASTER TO MASTER_CONNECT_RETRY = 10; - 所有参数修改后都需重启 IO 线程才生效,不能只靠
SET GLOBAL - 心跳 event 不写入 relay log,但依赖
binlog_format = ROW才能稳定发送
中间设备清空连接,MySQL 参数再细也没用
防火墙、NAT 网关、云厂商 SLB 都可能在 TCP 连接空闲几十秒后主动清理连接表项。此时光调 slave_net_timeout 和心跳毫无意义。
- 必须在操作系统层开启 TCP keepalive:
net.ipv4.tcp_keepalive_time建议设为60,net.ipv4.tcp_keepalive_intvl和net.ipv4.tcp_keepalive_probes配合使用 - MySQL 层的
MASTER_HEARTBEAT_PERIOD是应用层心跳,无法替代系统级 TCP keepalive - 若用云数据库(如阿里云 RDS、腾讯云 CDB),需确认其代理层是否透传心跳包;部分云厂商会截断或忽略 MySQL 自定义心跳
slave_net_timeout 的生效前提是连接已建立且空闲;而连接建立失败(如认证超时、DNS 解析慢)走的是另一套路径,受 connect_timeout 和 DNS 缓存影响,和它完全无关。**

















