MySQL主从复制架构中,从库的IO线程会从主库拉取binlog并写入本地的中继日志(relay log),SQL线程则读取中继日志执行同步操作。如果中继日志出现读取失败或者损坏,会直接导致同步中断,需要从根因排查并修复。

一、中继日志读取失败的常见原因
中继日志读取失败通常伴随从库同步报错,常见原因可以分为以下几类:
- 中继日志文件被误删除、移动或者权限被修改,导致SQL线程无法读取文件内容
- 服务器异常断电、磁盘故障,导致中继日志写入不完整或者文件损坏
- 主从复制位点信息记录错误,relay_log_info_repository中记录的日志位置与实际文件不匹配
- MySQL版本升级或者配置文件修改后,中继日志格式不兼容
二、中继日志读取失败的排查步骤
1. 查看从库同步状态
首先执行以下命令查看从库的同步报错信息:
SHOW SLAVE STATUSG
重点关注Last_SQL_Error字段,会明确提示中继日志相关的错误信息,比如日志文件不存在、读取偏移量错误、日志校验失败等。
2. 检查中继日志文件状态
进入MySQL的数据目录,查看中继日志文件是否存在,权限是否正确:
# 查看中继日志列表 ls -lh relay-log.* # 查看文件权限,确保mysql用户有读取权限 ls -l relay-log.000001
3. 校验中继日志完整性
可以使用MySQL自带的mysqlbinlog工具解析中继日志,判断文件是否损坏:
mysqlbinlog relay-log.000001 > /dev/null
如果命令执行报错,说明中继日志已经损坏,需要根据情况选择修复方案。
三、中继日志损坏的处理方案
1. 跳过损坏的中继日志(适用于少量日志损坏场景)
如果损坏的是个别中继日志,且数据差异较小,可以跳过对应的错误继续同步:
-- 停止从库同步 STOP SLAVE; -- 跳过1个错误事件,可根据报错次数调整数值 SET GLOBAL sql_slave_skip_counter = 1; -- 重新启动同步 START SLAVE;
注意这种方式可能会导致少量数据不一致,后续需要校验主从数据差异。
2. 重新初始化中继日志(适用于日志大面积损坏场景)
如果中继日志损坏严重,无法直接修复,可以重新拉取主库binlog生成新的中继日志:
-- 停止从库同步 STOP SLAVE; -- 重置从库的中继日志和同步位点信息 RESET SLAVE; -- 重新配置主库连接信息,注意这里需要指定正确的主库binlog位点 CHANGE MASTER TO MASTER_HOST='主库IP', MASTER_PORT=3306, MASTER_USER='同步账号', MASTER_PASSWORD='同步密码', MASTER_LOG_FILE='主库当前的binlog文件名', MASTER_LOG_POS=主库当前的binlog偏移量; -- 启动同步 START SLAVE;
主库的当前binlog位点可以通过在主库执行SHOW MASTER STATUS获取,也可以根据从库之前同步的最后一个成功执行的事件来推算。
3. 基于数据全量同步恢复(适用于数据差异较大场景)
如果中继日志损坏导致主从数据差异过大,跳过或者重置日志无法保证数据一致性,可以使用mysqldump或者xtrabackup重新全量同步从库数据,之后再重新搭建主从复制。
四、预防中继日志损坏的建议
- 避免手动修改、删除从库的数据目录下的中继日志文件,除非明确知道操作影响
- 定期检查服务器磁盘健康状态,避免磁盘故障导致文件损坏
- 重要业务的主从架构可以开启中继日志自动修复参数,或者定期备份中继日志信息
- 主从切换、版本升级前提前做好数据校验,避免配置不兼容导致日志解析失败