真正判断主从延迟需综合Slave_IO_Running、Slave_SQL_Running、Read_Master_Log_Pos、Exec_Master_Log_Pos和Seconds_Behind_Master五字段交叉验证,而非依赖失真的Seconds_Behind_Master;重点区分真假延迟、定位IO或SQL线程卡点,并用pt-heartbeat验证真实延迟。

直接看 SHOW SLAVE STATUS\G 里的五个字段,5分钟内就能锁定是 IO 卡了、SQL 卡了,还是压根没卡——别盯着 Seconds_Behind_Master 硬猜。
先分真假延迟:Seconds_Behind_Master 高 ≠ 真延迟
这个值受主从时钟差、sync_binlog 设置、大事务执行中等多种因素干扰,经常“报假警”。必须结合其他字段交叉验证:
-
Slave_IO_Running和Slave_SQL_Running必须都为Yes,否则不是延迟,是同步中断 -
Read_Master_Log_Pos和Exec_Master_Log_Pos差距大 +Seconds_Behind_Master持续 ≥30s → SQL 线程回放慢(90% 的 case) -
Read_Master_Log_Pos停滞不动 → IO 线程卡住(网络、权限、主库 dump 线程异常) -
Read_Master_Log_Pos和Exec_Master_Log_Pos同步上涨但Seconds_Behind_Master很高 → 主从服务器时钟不同步,或主库 binlog 写入延迟(如sync_binlog=0)
生产环境务必用 pt-heartbeat 验证:pt-heartbeat -D test --monitor -h 从库IP -u 用户 -p 密码,它写心跳表、读时间戳,绕过所有时钟和 binlog 时间戳陷阱。
IO 线程卡住:查网络、权限、主库状态
现象是 Slave_IO_Running: Connecting 或 Last_IO_Error 非空。重点排查:
- 用
ping和traceroute测主从间延迟与丢包,特别注意云厂商安全组/ACL 是否放行 3306 端口 - 检查从库
mysql.user表里复制账号的host是否匹配主库实际 IP(别信%,要精确) - 在主库执行
SHOW PROCESSLIST,找Binlog Dump状态是否为Writing to net;如果是Sending binlog event卡住,可能是主库磁盘满或 binlog 切换失败 - 确认主库
max_allowed_packet≥ 从库该参数,否则大事务 binlog 包被截断,IO 线程静默失败
SQL 线程卡住:盯锁、DDL、大事务、硬件瓶颈
现象是 Slave_SQL_Running: Yes 但 Exec_Master_Log_Pos 长期不动,或缓慢爬升。常见原因:
- 执行
SHOW PROCESSLIST,看State字段:出现Waiting for table metadata lock→ 主库刚跑完ALTER TABLE,从库 SQL 线程在等 MDL 锁 - 出现
Updating或Copying to tmp table且持续 >30s → 正在回放一个大事务(比如百万级INSERT ... SELECT),单线程扛不住 - 用
iostat -x 1看从库%util是否长期 >90%,await是否 >20ms → 磁盘 IO 瓶颈,尤其是 HDD 或低 IOPS 云盘 - 查
SHOW VARIABLES LIKE 'slave_parallel_workers',MySQL 5.7+ 必须 >0 才启用并行复制;设为 0 就是纯单线程,再快的 CPU 也白搭
注意:SHOW ENGINE INNODB STATUS\G 里的 TRANSACTIONS 部分能直接看到 SQL 线程卡在哪条语句、等什么锁。
为什么 pt-heartbeat 是金标准?
Seconds_Behind_Master 计算依赖主库事件时间戳 last_master_timestamp,而这个时间戳是 binlog 写入时间,不是事务提交时间。当 sync_binlog=0 或事务批量刷盘时,时间戳严重滞后,导致延迟值失真。更糟的是,大事务执行中,该值会归零——看起来“好了”,其实 SQL 线程还在死磕。
pt-heartbeat 绕开所有这些陷阱:它在主库定时更新一张心跳表,在从库读取该记录的时间差,本质是端到端真实延迟。只要心跳表可写可读,结果就可信。线上不配它,等于闭眼开车。


















