1594错误本质是中继日志损坏,无法解析事件;sql_slave_skip_counter无效,因CRC校验失败导致事件根本不可读,强行跳过会破坏事务一致性;应基于Master_Log_File和Read_Master_Log_Pos重设SQL线程起点,GTID模式需先禁用AUTO_POSITION再操作。

1594 错误本质是中继日志(relay log)损坏,不是主库 binlog 问题,也不是网络或权限问题;直接跳过事件或用 sql_slave_skip_counter 无效,反而可能破坏事务一致性。
为什么不能用 sql_slave_skip_counter 修复 1594
该参数只对“可解析但需跳过”的事件生效,而 1594 是 CRC 校验失败导致日志根本无法解析——MySQL 连事件结构都读不出来,sql_slave_skip_counter 完全不触发。执行后仍报错,且可能让 SQL 线程跳到事务中间位置,造成主从数据断裂。
-
sql_slave_skip_counter=1对Event crc check failed类错误无任何作用 - 强行设置后执行
START SLAVE,SQL 线程仍卡在相同位置,Last_Errno不变 - 若跳过的是事务开头(如 BEGIN 或 DML 前的 GTID_LOG_EVENT),后续语句会因缺失上下文而执行失败
如何安全定位并重设 relay log 起始坐标
核心思路是:放弃已损坏的 relay log,让 SQL 线程从 IO 线程最新拉取到的主库 binlog 位置重新解析执行。关键不是看 Relay_Master_Log_File 和 Exec_Master_Log_Pos(它们指向损坏日志里的旧位点),而是看 Master_Log_File 和 Read_Master_Log_Pos(IO 线程当前读到哪了)。
- 先确认 IO 线程正常:
Slave_IO_Running: Yes且Read_Master_Log_Pos在持续增长 - 记下这两个值:
Master_Log_File(如mysql-bin.001078)和Read_Master_Log_Pos(如670812995) - 停 SQL 线程:
STOP SLAVE SQL_THREAD;(保留 IO 线程继续接收新日志) - 清空 relay log:
RESET SLAVE;(RESET SLAVE ALL会清掉连接信息,不必要) - 重设起点:
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.001078', MASTER_LOG_POS=670812995; - 启动 SQL 线程:
START SLAVE SQL_THREAD;
GTID 模式下必须切换为基于位置的复制再操作
如果原配置是 AUTO_POSITION=1,直接执行 CHANGE MASTER TO ... MASTER_LOG_FILE 会报错 ERROR 1776。必须先关闭 GTID 自动定位,否则命令被拒绝。
- 先执行:
CHANGE MASTER TO MASTER_AUTO_POSITION=0; - 再执行
RESET SLAVE;(此时 GTID 相关状态也被清除) - 然后用
MASTER_LOG_FILE和MASTER_LOG_POS重设 - 恢复 GTID 模式(可选):
SET GLOBAL gtid_purged='03b8b27c-f9b8-11e8-b9e5-000c29cc1e94:396662759-397477758'; CHANGE MASTER TO MASTER_AUTO_POSITION=1;(需确保gtid_purged准确覆盖已执行事务)
最易忽略的检查点:主库 binlog 是否还存在
重设坐标后,SQL 线程会立刻去主库拉取 MASTER_LOG_FILE 文件。如果该文件已在主库被 purge,从库会卡在 Waiting for master to send event 或报 Could not find first log file name in binary log index file。
- 登录主库,执行:
SHOW BINARY LOGS;,确认MASTER_LOG_FILE仍在列表中 - 若已被清理,需从更早的 binlog 文件 + 位点重试,或启用
relay_log_recovery=ON并重启 MySQL(但需停服) - 日常应监控
expire_logs_days,确保其大于从库最大延迟时间


















