必须先检查Slave_IO_Running和Slave_SQL_Running是否均为Yes,再判断Seconds_Behind_Master:任一为No时该值不可信,此时应优先查看Last_IO_Error或Last_SQL_Error。

查 Seconds_Behind_Master 前先确认复制线程是否真在运行
很多人一查 Seconds_Behind_Master 是 NULL 或 0 就以为没延迟,其实可能复制早就断了。NULL 表示 SQL 线程没在运行(比如 IO 线程已停、SQL 线程报错退出、或刚启动还没开始执行 relay log),这时候看这个值毫无意义。
必须连带检查 Slave_IO_Running 和 Slave_SQL_Running 两个字段:
-
Slave_IO_Running: Yes→ 从库能连上主库,且在持续拉取 binlog -
Slave_SQL_Running: Yes→ 从库正在解析并执行 relay log 中的事件 - 任一为
No,Seconds_Behind_Master就不可信,优先查Last_IO_Error或Last_SQL_Error
SHOW SLAVE STATUS 返回的 Seconds_Behind_Master 是怎么算出来的
它不是“当前时间减去最后一条事件的时间戳”,而是基于主库 binlog 中事件的 original_commit_timestamp(MySQL 5.7+)或更朴素的逻辑:比较 SQL 线程执行到的位置和 IO 线程已拉取到的位置之间的时间差。前提是主从都开启了 log_bin 且主库启用了 binlog_format=ROW(语句级复制下误差更大)。
关键限制:
- 主库未开启
log_bin?从库Seconds_Behind_Master永远显示NULL - 主库时钟不准(比如 NTP 未同步),这个值会严重失真,甚至出现负数
- 大事务(如单条
UPDATE影响百万行)执行中,该值会卡在某个数字不动,直到事务提交才跳变——不代表实时延迟,只反映“已提交事务”的滞后
用命令行快速监控,别只靠一次 SHOW SLAVE STATUS
人工登录进 MySQL 执行 SHOW SLAVE STATUS\G 看一眼,容易漏掉瞬时抖动或缓慢爬升的趋势。线上应该用脚本定期采样,重点盯三个东西:Seconds_Behind_Master、Slave_IO_Running、Slave_SQL_Running。
一个最小可用的监控命令(Linux):
mysql -uuser -p'pwd' -e "SHOW SLAVE STATUS\G" 2>/dev/null | grep -E "(Seconds_Behind_Master|Slave_IO_Running|Slave_SQL_Running)"
注意点:
- 别用
SELECT Seconds_Behind_Master FROM information_schema.slave_status—— 这张表在 MySQL 8.0.22+ 已被移除,且旧版本权限要求高 - 避免高频查询(如每秒一次),
SHOW SLAVE STATUS有轻微锁开销,10 秒粒度足够发现异常 - 如果返回空,大概率是连接失败或权限不足,不是复制正常——得把错误也纳入判断逻辑
超过阈值后光报警不够,得知道下一步查什么
Seconds_Behind_Master > 60 不是终点,只是起点。真正卡住的地方往往不在复制协议层,而在从库自身负载或主从配置差异上:
- 查
SHOW PROCESSLIST:SQL 线程是不是卡在Waiting for table metadata lock或Updating?说明有长事务或 DDL 阻塞 - 对比主从
innodb_buffer_pool_size:从库内存太小,relay log 回放时频繁刷脏页,拖慢 SQL 线程 - 检查主库
max_allowed_packet和从库是否一致:不一致会导致大事务中断,IO 线程反复重连 - 留意
Relay_Log_Space是否持续增长:说明 SQL 线程跟不上,但 IO 线程还在猛拉,磁盘可能被撑爆
延迟本身不危险,危险的是你把它当孤立指标来看——它永远是个症状,不是病因。


















