MySQL relay log 作用与复制中断排查实战

引言

在 MySQL 主从复制架构中,relay log(中继日志)是连接主库与从库数据一致性的关键纽带。很多开发者和运维人员在遇到主从延迟、复制中断时,往往第一时间去检查 binlog 或网络,却忽略了 relay log 这个“中间站”。本文将从 relay log 的本质作用出发,结合常见复制中断场景,给出一套可落地的排查思路。这也是 MySQL 面试中高频出现的考点,理解透彻能让你在面试和实战中都游刃有余。

一、relay log 是什么?为什么需要它?

1.1 基本定义

relay log 是从库(slave/replica)特有的一种日志文件,由从库的 I/O 线程负责写入。它记录了从主库 binlog 中读取到的所有事件(event),本质上就是主库 binlog 在从库上的“本地副本”。

1.2 工作流程

MySQL 主从复制涉及三个核心线程:

  • 主库 dump 线程:监听 binlog 变化,将事件发送给从库。
  • 从库 I/O 线程:接收主库发来的事件,写入 relay log。
  • 从库 SQL 线程:读取 relay log 中的事件,在从库上重放(apply)。

流程可以简化为:

主库 binlog → dump线程 → 网络传输 → 从库I/O线程 → relay log → 从库SQL线程 → 从库数据

1.3 relay log 的核心作用

  1. 解耦网络传输与 SQL 重放:I/O 线程只需快速接收并落盘,SQL 线程可以按自己的节奏重放,两者互不阻塞。
  2. 断点续传的基础:从库通过 relay-log.info 记录已重放的位置,即使 SQL 线程中断,重启后也能从正确位置继续。
  3. 数据安全缓冲:当从库 SQL 线程因锁冲突、大事务等原因延迟时,relay log 可以暂存事件,避免数据丢失。
  4. 支持多线程复制:在并行复制(MTS)模式下,relay log 中的事件按逻辑时钟分组,供多个 worker 线程并发重放。

二、relay log 相关参数与文件结构

常用参数:

参数 说明
relay_log 指定 relay log 文件名(默认 hostname-relay-bin)
relay_log_purge 是否自动清理已重放的 relay log,默认 ON
relay_log_recovery 崩溃恢复时是否自动从 SQL 线程位置重新拉取,建议 ON
max_relay_log_size 单个 relay log 大小上限
sync_relay_log 每次写入后是否刷盘,1 为最安全

文件结构通常包括:

  • relay-bin.000001relay-bin.000002……:实际的 relay log 文件。
  • relay-bin.index:索引文件,记录所有 relay log 列表。
  • relay-log.info:记录当前 I/O 线程和 SQL 线程的位置(MySQL 8.0 后逐步被 mysql.slave_relay_log_info 表替代)。

三、复制中断的常见原因分类

复制中断通常表现为 Slave_SQL_Running: NoSlave_IO_Running: No。排查前先执行:

SHOW SLAVE STATUS\G

重点关注:

  • Slave_IO_Running / Slave_SQL_Running
  • Last_IO_Error / Last_SQL_Error
  • Seconds_Behind_Master
  • Relay_Log_File / Relay_Log_Pos
  • Relay_Master_Log_File / Exec_Master_Log_Pos

3.1 I/O 线程中断

常见原因:

  • 网络不通或防火墙拦截。
  • 主库 binlog 被清理,从库请求的位置已不存在(Could not find first log file name)。
  • 主从 server_id 冲突。
  • 账号权限不足或密码错误。

3.2 SQL 线程中断

常见原因:

  • 主键冲突 / 唯一键冲突(1062):从库已有相同数据。
  • 找不到记录(1032):从库缺少主库要更新/删除的行。
  • 表不存在(1146):主从表结构不一致。
  • 字段不存在或类型不匹配:DDL 未同步。
  • 大事务导致延迟:relay log 堆积,SQL 线程长时间未推进。

四、基于 relay log 的排查实战

4.1 定位当前重放位置

SHOW SLAVE STATUS\G
-- 关注 Relay_Log_File 和 Relay_Log_Pos

使用 mysqlbinlog 解析 relay log,查看具体事件:

mysqlbinlog --base64-output=decode-rows -v \
  /var/lib/mysql/relay-bin.000005 > relay_decode.sql

在输出中搜索 Last_SQL_Error 提示的 position,定位到出错的具体 SQL。

4.2 典型场景:1032 错误排查

假设 Last_SQL_Error 提示:

Could not execute Update_rows event on table db.t1;
Can't find record in 't1', Error_code: 1032

步骤:

  1. 记录 Relay_Log_FileRelay_Log_Pos
  2. mysqlbinlog 解析该 relay log,找到对应 event。
  3. 对比主库该行数据与从库该行数据,确认缺失原因。
  4. 处理方式:
    • 若是可忽略的数据不一致,可临时跳过:
      STOP SLAVE SQL_THREAD;
      SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
      START SLAVE SQL_THREAD;
      
    • 若是数据确实缺失,手工补数据后再启动。
    • 更稳妥的方式:用 pt-slave-restartpt-table-sync 工具修复。

4.3 典型场景:relay log 损坏

若 relay log 文件损坏,SQL 线程可能报错无法读取。此时可:

STOP SLAVE;
RESET SLAVE;  -- 清空 relay log
CHANGE MASTER TO ...;  -- 重新指定主库位置
START SLAVE;

注意:RESET SLAVE 会删除所有 relay log,务必先确认可重新从主库拉取。

4.4 大事务导致 relay log 暴涨

当主库执行大事务(如一次性更新百万行),relay log 会迅速膨胀,SQL 线程重放缓慢。排查:

SHOW SLAVE STATUS\G
-- 观察 Relay_Log_Space 是否持续增长

解决思路:

  • 拆分大事务为小批量。
  • 开启并行复制(slave_parallel_workers > 0)。
  • 调整 relay_log_purge 与磁盘容量。

五、面试高频问答

Q1:relay log 和 binlog 有什么区别?

binlog 记录主库所有变更,格式为逻辑日志;relay log 是从库对主库 binlog 的本地副本,内容基本一致,但由从库 I/O 线程写入、SQL 线程消费。binlog 用于复制和恢复,relay log 仅用于从库重放。

Q2:relay_log_recovery 的作用是什么?

当从库崩溃重启时,若 relay_log_recovery=ON,从库会丢弃所有未执行的 relay log,重新从 Relay_Master_Log_File 位置向主库请求事件,避免因 relay log 不完整导致的数据不一致。

Q3:如何判断复制中断是 I/O 还是 SQL 线程问题?

Slave_IO_RunningSlave_SQL_Running。IO 为 No 说明拉取失败,检查网络、主库 binlog、账号;SQL 为 No 说明重放失败,检查 Last_SQL_Error 和 relay log 中的具体事件。

Q4:relay log 会自动删除吗?

默认 relay_log_purge=ON,SQL 线程执行完的 relay log 会被自动清理。若设置为 OFF,需手动清理,否则磁盘会被占满。

六、总结

relay log 是 MySQL 复制链路中的“缓冲带”和“断点记录器”,理解它的写入与消费机制,是排查复制中断的基础。遇到复制问题时,建议按以下顺序排查:

  1. SHOW SLAVE STATUS\G 看线程状态和错误信息。
  2. 区分 I/O 与 SQL 线程问题。
  3. mysqlbinlog 解析 relay log 定位具体事件。
  4. 根据错误码(1032、1062、1146 等)采取跳过、补数据或重建复制。
  5. 长期优化:开启并行复制、拆分大事务、监控 relay log 空间。

掌握这套方法,无论是面试还是生产故障处理,都能做到心中有数、手中有术。

未经允许不得转载:任鹏个人博客 » MySQL relay log 作用与复制中断排查实战

赞 (0) 打赏

评论 0

取消
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏