relay_log_recovery=on是首选方案,因其在mysql启动时自动丢弃损坏relay log并从master.info或gtid位点重建,实现安全恢复而非跳过;动态设置无效,必须静态配置并重启生效。

1594 错误本质是中继日志(relay log)损坏,不能靠跳过单条事件修复;relay_log_recovery=ON 是唯一安全、自动化的恢复机制,其他“跳过”方案极易导致数据不一致。
为什么 relay_log_recovery=ON 是首选方案
MySQL 在启动时若检测到 SQL 线程上次异常退出,且 relay_log_recovery=ON,会自动丢弃当前不完整的 relay log 文件,并从 master.info 或 GTID 位点重新拉取主库 binlog 重建 relay log。这不是“跳过”,而是“重建”。
常见误区是以为设置 sql_slave_skip_counter=1 能解决 1594 —— 实际上该参数对 CRC 校验失败完全无效,执行后仍报错,且可能跳过完整事务开头,造成主从数据断裂。
-
relay_log_recovery必须在 MySQL 配置文件(如/etc/my.cnf)中静态配置,SET GLOBAL动态修改不生效 - 启用后需重启 mysqld 才触发恢复逻辑,不是 START SLAVE 就能激活
- 仅对 relay log 损坏有效;若主库 binlog 已损坏,此参数无用
- GTID 模式下必须配合
enforce_gtid_consistency=ON和gtid_mode=ON才能准确定位重拉起点
手动重建 relay log 的前提与操作步骤
当无法重启 MySQL(例如生产环境不允许停服),或 relay_log_recovery 未启用且已出错,才考虑手动干预。核心原则:放弃损坏的 relay log,从 IO 线程最新已拉取位置重新同步。
- 先确认 IO 线程状态:
SHOW SLAVE STATUS\G中Slave_IO_Running: Yes且Read_Master_Log_Pos有进展,说明主库日志还在持续接收 - 记录当前
Master_Log_File和Read_Master_Log_Pos—— 这是 IO 线程最新读到的主库位点,不是损坏的 relay log 位置 - 停掉 SQL 线程:
STOP SLAVE SQL_THREAD;(保留 IO 线程继续拉日志) - 清空 relay log:
RESET SLAVE;或更精准地RESET SLAVE ALL;(后者同时清空master.info和relay-log.info) - 重新指向主库位点:
CHANGE MASTER TO MASTER_LOG_FILE='xxx', MASTER_LOG_POS=yyy;(用上面记下的Master_Log_File和Read_Master_Log_Pos) - 启动 SQL 线程:
START SLAVE SQL_THREAD;
注意:CHANGE MASTER TO 前必须确保 MASTER_AUTO_POSITION=0,否则会报 ERROR 1776;如果原为 GTID 模式,应改用 SET GLOBAL gtid_purged='...'; CHANGE MASTER TO MASTER_AUTO_POSITION=1;。
mysqlbinlog --verify-binlog-checksum 验证 relay log 损坏位置
该命令是定位问题的黄金工具,不是可选项。它能明确告诉你哪一行校验失败,从而判断是局部损坏还是整个文件不可用。
- 从
SHOW SLAVE STATUS获取Relay_Log_File(如mysql-relay.000012) - 执行:
mysqlbinlog --verify-binlog-checksum /var/lib/mysql/mysql-relay.000012 2>&1 | head -n 50 - 若输出含
CRC check failed或直接报错退出,说明该文件已损坏,不可信任 - 若命令成功返回 event 列表,但
Relay_Log_Pos对应位置之后的内容解析失败,说明损坏发生在文件末尾,此时可尝试CHANGE MASTER TO跳到前一个完整事务起始点(需结合mysqlbinlog -v分析)
别依赖 hexedit 或 dd 修补 relay log —— MySQL 日志是变长二进制结构,手动修复几乎必然失败。
容易被忽略的底层风险点
1594 很少孤立发生。真正危险的是背后隐藏的硬件或系统问题:
- 检查磁盘健康:
smartctl -a /dev/sdX看 Reallocated_Sector_Ct、Pending_Sector 等指标,坏道会导致 relay log 写入静默损坏 - 确认文件系统挂载参数是否含
data=ordered或data=journal(ext4),禁用barrier=0可能引发日志写入乱序 - 排查内核日志:
dmesg -T | grep -i "ext4.*error\|ata.*exception",看是否有 I/O 错误或 RAID 卡告警 -
max_allowed_packet虽常被怀疑,但 1594 报错本身不反映该参数问题;若事务过大,通常先报 1153(ER_NET_PACKET_TOO_LARGE)而非 1594
一次 1594 恢复后,务必验证主从数据一致性(如用 pt-table-checksum),因为损坏可能已导致部分事务被截断写入,表面恢复了,实际少了几行数据。











