Slave_SQL_Running为Yes但数据不一致,说明SQL线程已处理完当前中继日志,但Executed_Gtid_Set与Retrieved_Gtid_Set不等,可能因静默跳过、锁等待或GTID空洞导致;Relay_Master_Log_File与Master_Log_File不一致表明SQL线程滞后于IO线程,真实延迟已存在。

Slave_SQL_Running为Yes但数据不一致
这说明SQL线程已处理完当前中继日志(Relay_Log_Pos追到末尾),但不代表数据与主库一致。关键要看Executed_Gtid_Set和Retrieved_Gtid_Set是否相等 —— 若不等,说明SQL线程卡在某条事务上,只是没报错、没停,而是“静默跳过”或“阻塞等待锁”。常见于GTID模式下启用了slave_skip_errors但未记录跳过细节,或事务因死锁/超时被回滚后未重试。
Relay_Master_Log_File和Master_Log_File不一致
从库的Relay_Master_Log_File(SQL线程实际执行的binlog文件)和Master_Log_File(IO线程最新拉取的binlog文件)不一致,说明IO线程还在拉新日志,但SQL线程没跟上。此时Seconds_Behind_Master可能为0或NULL,但真实延迟已存在。典型诱因包括:
- 主库大事务写入,从库单线程SQL执行慢(尤其MySQL 5.7及之前)
- 从库表缺少索引,导致
UPDATE/DELETE全表扫描 -
replicate_wild_do_table配置不当,过滤掉部分事件,造成逻辑缺失
Got fatal error 1236:Could not find first log file name
错误信息表面是“找不到binlog文件”,本质是Master_Log_File指向的文件在主库上已被PURGE BINARY LOGS或expire_logs_days清理。此时IO线程无法继续拉取,但SQL线程仍能跑完已有relay log,所以出现“读完relay log却不同步”。验证方法:
在从库执行SHOW SLAVE STATUS\G,取出Master_Log_File值;再登录主库执行SHOW BINARY LOGS,确认该文件是否存在。若已丢失,CHANGE MASTER TO无法修复,必须重建从库或(仅GTID模式)用SET GLOBAL gtid_purged = '...'补全缺失集合 —— 但稍有偏差就会失败。
Relay log read failure导致静默中断
Last_SQL_Error: Relay log read failure: Could not parse relay log event entry这类错误有时不会让Slave_SQL_Running直接变No,尤其在旧版本MySQL中,SQL线程可能进入不可恢复的解析异常状态,后续事件被丢弃。此时Relay_Log_Pos停滞,Relay_Master_Log_File不再更新,但状态仍显示Running。最稳妥的判断方式是检查Relay_Log_Space是否持续不增长,再用mysqlbinlog /var/lib/mysql/xxx-relay-bin.0000xx手动解析中继日志看是否可读。
真正棘手的是那些不报错、不中断、但数据已分叉的情况 —— 比如跨库操作被replicate-do-db过滤、GTID空事务注入后未校验Executed_Gtid_Set、或read_only=OFF时从库被误写。这些都得靠定期比对主从表级checksum,不能只信Seconds_Behind_Master。


















