slave_net_timeout必须大于master_heartbeat_period(推荐至少2倍),否则连接先断开导致心跳无法发出;需配合source_connection_auto_retry=1等参数并重启复制线程才生效。

slave_net_timeout设太小,心跳还没发就断连
心跳包(MASTER_HEARTBEAT_PERIOD)是主库主动发的,但它的发送前提是连接还活着。如果 slave_net_timeout 设得太小(比如 5 秒),而主库写入稀疏、又没开启心跳,从库 IO 线程会在空闲满 5 秒后直接断开连接——此时心跳根本没机会发出,自然“失效”。这不是心跳坏了,是连接先被砍了。
实操建议:
-
slave_net_timeout必须 >MASTER_HEARTBEAT_PERIOD(推荐至少 2 倍以上,如心跳设 10 秒,超时至少设 25 秒) - 心跳值不能大于
slave_net_timeout,否则会报错ER_SLAVE_HEARTBEAT_PERIOD_GREATER_THAN_MAX - MySQL 5.7+ 中,
MASTER_HEARTBEAT_PERIOD默认是slave_net_timeout / 2,改超时值后必须显式重设心跳,否则沿用旧默认
SHOW SLAVE STATUS 看不到心跳配置,误判为未启用
MASTER_HEARTBEAT_PERIOD 不在 SHOW SLAVE STATUS 输出里,查不到不等于没生效。它藏在状态变量中,且名字容易拼错。
排查方法:
- 执行
SHOW STATUS LIKE 'Slave_heartbeat_period'(注意下划线,不是横线) - 同时检查
SHOW STATUS LIKE 'Slave_received_heartbeats'是否在增长 - 若返回空或为 0,说明心跳确实没启用;若数值持续上升,说明心跳正常,问题不在这里
IO 线程没挂,但 Seconds_Behind_Master 暴涨,以为是心跳失效
很多人看到延迟飙升、Slave_IO_Running: Yes 就认定“心跳起了作用”,其实完全相反:只要 IO 线程还在跑,slave_net_timeout 就不会触发,心跳机制也压根不参与判断。这时候延迟暴涨,大概率是 SQL 线程卡住(比如大事务、主键冲突 Error_code: 1062、无主键表 Error_code: 1032),和网络、心跳全无关系。
关键动作:
- 先看
Slave_SQL_Running是否为Yes;否,则翻错误日志找具体报错 - 若 SQL 线程是 Yes,再看
Exec_Master_Log_Pos和Read_Master_Log_Pos是否同步前进 -
Relay_Log_Space持续上涨 +Exec_Master_Log_Pos不动 → SQL 回放瓶颈,不是心跳问题
MySQL 8.0.22+ 改用 SOURCE_CONNECTION_AUTO_RETRY,旧参数失效
8.0.22 起,MASTER_CONNECT_RETRY 和 MASTER_RETRY_COUNT 已被弃用。只改 slave_net_timeout 或设旧参数,自动重连不会发生。
必须组合使用:
CHANGE REPLICATION SOURCE TO SOURCE_CONNECTION_AUTO_RETRY = 1-
CHANGE REPLICATION SOURCE TO SOURCE_RETRY_COUNT = N(N 建议设为 86400) -
SET GLOBAL slave_net_timeout = X(X 推荐 25–30) - 三者缺一不可,且必须执行
STOP REPLICA; START REPLICA;才真正加载
最常被忽略的是:调完参数不重启复制线程,所有配置都只是内存变量,IO 线程继续按旧逻辑跑。











