relay_log_recovery=ON 不会报错,而是启动时自动跳过损坏relay log并重建;真正需排查的是磁盘满、异常终止等导致relay log损坏的根源。

relay-log-recovery 不会导致报错,它本身是修复 1594 类错误的手段,不是错误源;真正要定位的是 relay log 损坏本身——而 relay_log_recovery=ON 启用后反而会让 MySQL 在启动时自动跳过损坏日志并重建,你根本看不到 1594 错误。
为什么查不到 relay_log_recovery 相关错误
该参数是恢复机制,不是触发条件:relay_log_recovery 是个开关,设为 ON 后,MySQL 只在 mysqld 启动时检查 SQL 线程是否异常退出、relay log 是否不完整;若检测到损坏,就静默丢弃当前 relay log 文件,并从 master.info 或 GTID 位点重新拉取 binlog —— 整个过程不报错、不写 error log,也不会在 SHOW SLAVE STATUS 里体现为异常。
常见误解是看到 1594 错误后去查 relay_log_recovery 配置,其实:
- 如果没配或配了但没重启,1594 会照常报出
- 如果已配且重启过,1594 根本不会出现,SQL 线程会直接从正确位置继续回放
- 动态执行 SET GLOBAL relay_log_recovery = ON 完全无效,必须写进配置文件并重启
如何确认 relay log 是否真损坏(而不是误判)
不能只看 Last_SQL_Error 里有没有 “CRC check failed” 或 “error 1594”,得交叉验证 IO 线程状态和位点一致性:
- 执行
SHOW SLAVE STATUS\G,重点比对两组位点:Master_Log_File/Read_Master_Log_Pos(IO 线程最新读到哪) vsRelay_Master_Log_File/Exec_Master_Log_Pos(SQL 线程最后执行到哪) - 如果
Slave_IO_Running: Yes且Read_Master_Log_Pos持续增长,但Exec_Master_Log_Pos卡死不动、Last_SQL_Error是 1594,则基本确定是 relay log 文件损坏(而非主库 binlog 问题) - 用
mysqlbinlog --base64-output=decode-rows -v /path/to/relay-log-file尝试解析对应 relay log 文件,若报 “invalid event” 或 “CRC mismatch”,即实锤损坏
GTID 模式下 relay_log_recovery 的特殊行为
启用 relay_log_recovery=ON 时,GTID 模式的行为和传统 position 模式不同:
使用 4 个 agent 部署一套备份与灾难恢复系统。在以下情况下使用该技能: 1. 用户希望搭建自动化的备份基础设施; 2. 用户正在配置……
- 它不依赖
master.info,而是读取gtid_executed和gtid_purged来确定重拉起点 - 要求
enforce_gtid_consistency=ON和gtid_mode=ON必须同时生效,否则可能拉错日志或卡住 - 如果从库曾手动执行过
SET GTID_NEXT或导入过非 GTID 数据,gtid_executed可能被污染,导致 recovery 后拉取范围错误——此时relay_log_recovery不会报错,但数据会不一致
所以 GTID 下启用该参数后,务必检查 SELECT @@GLOBAL.gtid_executed; 是否与主库 Executed_Gtid_Set 逻辑匹配,而不是只盯着有没有报错。
真正该监控的指标,不是 relay_log_recovery 本身
这个参数一旦配好并重启,就“隐身”了;运维重点应放在它能否生效的前置条件上:
- 磁盘空间是否充足:
relay_log_space_limit被突破或磁盘满,会导致 relay log 写入截断,这是损坏主因之一 - 从库是否被意外写入:
read_only=ON必须开启,否则 DML 可能破坏 relay log 原子性 - MySQL 进程是否异常终止:比如 kill -9、OOM killer 干掉 mysqld,这是
relay_log_recovery触发的唯一前提
换句话说,relay_log_recovery 是个“事后自动兜底”机制,它自己不出错,但它的生效依赖于你对底层稳定性的控制——这点最容易被忽略。

















