跨网段主从同步总是搞不定?先别急着怀疑配置写错了。90%的情况下,真正的罪魁祸首是网络抖动或防火墙悄悄把连接给掐断了。MySQL 8.0 默认的心跳机制处于关闭状态,必须依靠 MASTER_HEARTBEAT_PERIOD 配合底层的 TCP 参数一起上阵,才能稳住局势。

为什么 MASTER_HEARTBEAT_PERIOD 必须显式设置?
MySQL 8.0 的复制线程默认依赖系统级的 TCP keepalive 来维持连接活性。但问题在于,在跨网段、经过 NAT 或云厂商负载均衡器后,这个机制经常失效——连接空闲时间一长,中间设备就会静默断开,而 MySQL 自身还浑然不觉。此时,只有 CHANGE MASTER TO 中配置的 MASTER_HEARTBEAT_PERIOD 才能让主库主动发送心跳包,及时确认连接是否存活。
MASTER_HEARTBEAT_PERIOD的单位是秒,取值范围为 0 到 4294967。设为 0 表示禁用心跳,千万不可取。- 实际生产环境中,建议设置在 10 到 30 秒之间。太短会增加主库压力,太长则断连发现不及时。
- 该参数仅在执行
CHANGE MASTER TO时生效。调整后必须执行STOP SLAVE; START SLAVE;才能使其生效。 - 特别注意:它不等于
slave_net_timeout(从库等待主库回应的超时时间),二者需要配合调整。
slave_net_timeout 和 MASTER_HEARTBEAT_PERIOD 怎么配才不冲突?
这两个参数共同决定了“多长时间没收到任何数据,就判定主从连接断开”。配置不当,要么出现假断连,要么真断了半天恢复不过来。
slave_net_timeout是从库侧的全局变量,默认值为 60 秒。它必须大于MASTER_HEARTBEAT_PERIOD,否则心跳包还没来得及发出,就被判定超时了。- 推荐的组合方案:
MASTER_HEARTBEAT_PERIOD = 15,slave_net_timeout = 30。修改后重启从库,或直接执行SET GLOBAL slave_net_timeout = 30;。 - 如果网络延迟较高,例如跨省专线 RTT 超过 100 毫秒,那么
slave_net_timeout至少应设为MASTER_HEARTBEAT_PERIOD × 2 + 5。 - 修改
slave_net_timeout后,务必执行STOP SLAVE; START SLAVE;,否则新的超时时间不会生效。
跨网段还要调哪些 TCP 层参数?
光靠 MySQL 参数还不够。Linux 内核的 tcp_keepalive_* 系列参数会影响底层连接的存活状态,尤其是在有状态防火墙或 NAT 设备的路由环境下。
- 先检查当前值:
sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalive_probes - 推荐调整方案(写入
/etc/sysctl.conf):net.ipv4.tcp_keepalive_time = 600(首次探测前的空闲时间)net.ipv4.tcp_keepalive_intvl = 60(探测间隔)net.ipv4.tcp_keepalive_probes = 3(失败后重试次数) - 改完后执行
sysctl -p生效。注意,这是系统级设置,会影响所有 TCP 连接,不止 MySQL。 - 云环境,比如阿里云、AWS,可能会限制 keepalive 行为。需要确认安全组或网络 ACL 是否允许双向 ICMP 或 TCP keepalive 包通过。
怎么验证心跳是否真正起作用?
光看 SHOW SLAVE STATUS\G 里的 Seconds_Behind_Master 远远不够,必须抓取底层行为来验证。
- 在从库上执行
tcpdump -i any port 3306 -nn -A | grep -i "heartbeat"(需要安装 tcpdump)。实际上不会打印出 "heartbeat" 字样,但能观察到周期性收发的小包。 - 更可靠的方法是:直接停掉主库网卡 20 秒,观察从库的
Slave_IO_Running状态变化时间,是否与设置的slave_net_timeout接近。 - 查看错误日志:
tail -f /var/log/mysqld.log | grep -i "lost connection|heartbeat",确认断连原因是否为超时,而非认证失败。 - 注意:MySQL 8.0 的日志中不会直接出现 “heartbeat timeout”,而是报
error connecting to master或network error。
话说回来,跨网段主从最容易被忽略的,其实是中间设备对长连接的静默回收策略——它比 MySQL 自身的参数更早切断连接。所以,心跳不是“加了就稳”,而是必须与网络设备策略对齐。调参之后,一定要模拟一次网络闪断,否则上线后半夜出问题,想回溯都难。
