mysql主备心跳机制是内建于复制协议的保活与延迟感知机制,通过master_heartbeat_period参数由主库主动发送心跳事件,配合slave_last_heartbeat等状态变量实现故障快速发现;应用层还需独立心跳表支持高可用切换。

MySQL 主备(主从)心跳机制不是应用层“打点”式的心跳表,而是内建于复制协议底层的通信保活与延迟感知机制,核心作用是解决“静默断连”问题——即主库无写入时,从库无法区分是正常空闲还是网络中断。配合状态自动监控,才能实现故障快速发现和响应。
主从原生心跳参数:master_heartbeat_period
MySQL 5.5+ 提供 master_heartbeat_period 参数,单位为秒(支持毫秒精度,最小非零值 0.001),由主库主动发出心跳事件(不依赖 binlog 写入)。它本质是空闲期的“保活信号”,携带当前 binlog 文件名和位置(或 GTID 集合),让从库持续确认主库在线且状态可信。
- 默认值 = slave_net_timeout / 2(例如 slave_net_timeout=60,则默认心跳周期为 30 秒)
- 设为 0 表示禁用心跳
- 推荐显式设置:如
CHANGE MASTER TO master_heartbeat_period = 10;(10 秒一发) - 生效需重启复制:
STOP SLAVE; START SLAVE;
关键状态变量与实时监控项
心跳是否启用、是否收到、最近何时收到,均可通过以下状态变量验证:
- Slave_heartbeat_period:当前生效的心跳周期(秒)
- Slave_last_heartbeat:最后一次收到心跳的时间戳
- Slave_received_heartbeats:累计成功接收的心跳次数
- Seconds_Behind_Master:综合判断延迟的核心指标(注意:该值在 IO 线程异常时可能为 NULL 或 0,不可单独依赖)
- Slave_IO_Running 和 Slave_SQL_Running:必须均为 Yes 才表示复制线程正常
建议每 10–30 秒轮询一次 SHOW SLAVE STATUS\G,重点关注 Slave_IO_Running、Seconds_Behind_Master 和 Slave_last_heartbeat 的变化趋势。
应用层心跳表:用于高可用切换与服务健康检查
当主从架构之上叠加了中间件(如 MyCat、ProxySQL)或需要对外暴露“数据库是否可写/可读”状态时,需部署独立的心跳表。它不参与复制逻辑,但为上层提供可编程的健康信号:
- 建表语句(简洁版):
CREATE TABLE heartbeat (id TINYINT PRIMARY KEY, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB; - 主库定时更新(如每 5 秒):
INSERT INTO heartbeat VALUES(1, NOW()) ON DUPLICATE KEY UPDATE updated_at = NOW(); - 从库只读查询该表,结合时间差判断同步延迟(如
SELECT UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(updated_at) ) - HA 工具(如 Keepalived、MHA)或监控脚本可基于此 SQL 返回结果做自动切换或告警
自动监控落地建议
真正可用的监控不是“查一次状态”,而是构建闭环:
- 用脚本定期采集
SHOW SLAVE STATUS和心跳表时间戳,存入本地日志或时序数据库 - 设置多级阈值告警:如
Seconds_Behind_Master > 60触发警告;Slave_last_heartbeat超过 2× 心跳周期未更新 +Slave_IO_Running=No触发严重告警 - 避免仅依赖
Seconds_Behind_Master=0判定正常——它可能因 relay log 消费完毕而为 0,但 IO 线程早已中断 - 将
Slave_received_heartbeats增量变化率纳入监控,突降为 0 是网络抖动或主库异常的早期信号











