如何排查MySQL多源复制下某一特定通道日志不再同步的问题?

作者:袖梨 2026-07-13
查指定通道复制线程是否存活,必须用SHOW REPLICA STATUS FOR CHANNEL 'master1'G,关注Slave_IO_Running和Slave_SQL_Running是否均为Yes;若任一为No则通道中断,Seconds_Behind_Master失效;IO为Connecting说明网络、主库或权限问题,SQL为No且报错需人工干预;GTID模式下需比对Retrieved_Gtid_Set与Executed_Gtid_Set是否持续收敛。

查指定通道的复制线程是否存活

多源复制中,每个主库对应一个 Channel_name,状态不互通。不能只看 SHOW REPLICA STATUSG 的第一行——它默认返回第一个通道,容易漏掉异常通道。

必须显式指定通道名查询:

SHOW REPLICA STATUS FOR CHANNEL 'master1'G

重点关注:Slave_IO_RunningSlave_SQL_Running 是否都为 Yes;若任一为 No,该通道已中断,Seconds_Behind_Master 数值失效。

  • Slave_IO_Running = Connecting:大概率是网络不通、主库宕机、或复制用户权限失效
  • Slave_IO_Running = NoLast_IO_Error 提示 error connecting to master:检查主库 bind_address、防火墙、repl 用户是否允许从该 IP 登录
  • Slave_SQL_Running = NoLast_SQL_Error 显示 Duplicate entryTable doesn't exist:说明 SQL 线程卡在某条 DML 或 DDL 上,需人工干预

比对 GTID 集合是否持续收敛

GTID 模式下,Retrieved_Gtid_Set(已拉取但未执行)和 Executed_Gtid_Set(已执行)应逐步趋近。若两者长期不等,且 Retrieved_Gtid_Set 停滞不动,说明 IO 线程没在拉日志;若差值稳定增长但 Executed_Gtid_Set 不动,说明 SQL 线程堵死。

执行命令确认:

SELECT Channel_name, Retrieved_Gtid_Set, Executed_Gtid_Set FROM performance_schema.replication_connection_status WHERE Channel_name = 'master1';
  • Retrieved_Gtid_Set 为空或长时间不变 → IO 层问题(主库无新事务、网络断开、binlog 被 purge)
  • Retrieved_Gtid_Set 持续变大但 Executed_Gtid_Set 卡住 → SQL 层问题(如从库缺失表、字段类型不兼容、触发器报错)
  • 注意:GTID 模式下不能用 sql_slave_skip_counter,跳过需用 SET GTID_NEXT + 空事务方式,否则破坏 GTID 序列

检查 relay log 是否写满或损坏

从库磁盘满、relay log 文件损坏、或 relay_log_space_limit 设置过小,都会导致 IO 线程静默失败——不报错但停止写入,表现为 Relay_Log_Space 不再增长。

先查空间占用:

SELECT @@relay_log_space_limit, @@relay_log_purge;
  • relay_log_space_limit > 0 且磁盘剩余空间不足该值,IO 线程会暂停写入 relay log
  • relay_log_purge = OFF,旧 relay log 积压可能撑爆磁盘;建议保持 ON(默认)
  • 手动验证 relay log 是否可读:mysqlbinlog /var/lib/mysql/relay-log-bin.000001,报错则文件损坏,需清空 relay_log_index 并重启复制

确认主库 binlog 是否被提前清理

这是最隐蔽也最常被忽略的根源:主库 expire_logs_days 设得太小(比如 1 天),而某个通道因故障停顿超时,从库再连时请求的 Master_Log_File 已被 purge,错误信息通常是:

Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'

验证步骤:

  • 在从库查该通道当前位点:SELECT Master_Host, Master_Log_File, Read_Master_Log_Pos FROM performance_schema.replication_connection_status WHERE Channel_name = 'master1';
  • 登录主库执行:SHOW BINARY LOGS;,确认 Master_Log_File 是否还在列表中
  • 若已丢失,且该通道启用了 GTID,则需对比主库 gtid_executed 与从库 Executed_Gtid_Set,用 SET GLOBAL gtid_purged = 'xxx' 补齐缺失集合(务必确保 purged 集合完全覆盖缺失部分,否则仍失败)
  • 若非 GTID 模式,只能重做该通道:导出主库当前数据 + 新的 binlog position,重新 CHANGE MASTER TO ... FOR CHANNEL

真正麻烦的不是发现不同步,而是发现时已经丢了几天日志——所以日常必须监控 Retrieved_Gtid_Set 增长趋势和主库 binlog 存留周期,不能只盯 Seconds_Behind_Master

相关文章

精彩推荐