1032错误是因从库执行update/delete时目标行缺失,需通过master_log_file和read_master_log_pos(gtid模式下用retrieved_gtid_set末尾事务号)定位binlog位置,用mysqlbinlog解析出where条件,验证并补全数据后设sql_log_bin=0导入,再跳过当前事件恢复复制。

1032错误不是日志损坏,而是从库执行UPDATE或DELETE时目标行确实不存在——必须定位到具体哪一行、在哪条binlog里丢了,才能修复。
从SHOW SLAVE STATUS提取真实位点
只看Last_Error: Can't find record in 'db.t'毫无用处。关键要抓Master_Log_File和Read_Master_Log_Pos(注意不是Exec_Master_Log_Pos),例如:mysql-bin.000013和440267874。
- 在GTID模式下,若
Auto_Position: 1,Retrieved_Gtid_Set末尾的事务号才是真实位点,Read_Master_Log_Pos可能不准 -
Relay_Master_Log_File和Exec_Master_Log_Pos已滞后,不能用于定位原始操作 - 确认主库binlog路径:执行
SHOW VARIABLES LIKE 'datadir',别硬套/var/lib/mysql/
用mysqlbinlog反查WHERE条件
拿到文件名和position后,在主库执行:
mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS /var/lib/mysql/mysql-bin.000013 | grep -A 20 "end_log_pos 440267874"
输出中找以### DELETE FROM或### UPDATE开头的行,后面跟着类似WHERE @1=12345 AND @2='xxx'的内容——这就是缺失记录的完整定位条件。
-
@1通常对应表的第一列,但不绝对;必须结合SHOW CREATE TABLE确认字段顺序 - 表无主键时,
@1~@N是整行所有字段镜像,WHERE条件极长,且易因JSON空格、datetime毫秒等微小差异匹配失败 - 必须加
--base64-output=DECODE-ROWS,否则看到的是BASE64编码,无法人工识别
验证并补数据前必须设SQL_LOG_BIN = 0
拿到@1=12345这类条件后,先在主库验证该行是否存在:
SELECT * FROM db.t WHERE id = 12345;
存在才导出:
mysqldump --no-create-info --where="id=12345" db t > missing_row.sql
传到从库执行前,必须执行SET SQL_LOG_BIN = 0。
- GTID模式下强制要求,否则
INSERT会被记入从库binlog,再同步回主库,引发主键冲突或死循环 - 非GTID模式下,
SQL_LOG_BIN=0关闭后导入的数据不会进binlog,但需确保binlog_format = ROW - 导出时加
--skip-triggers避免触发器干扰;TEXT/JSON字段注意换行符未转义问题
补完数据后仍需手动推进SQL线程
补数据不等于复制自动恢复,SQL thread仍卡在原地。必须执行:
STOP SLAVE;<br>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;<br>START SLAVE;
然后检查SHOW SLAVE STATUS\G中Slave_SQL_Running: Yes且Seconds_Behind_Master开始下降。
- 若启用了
slave_exec_mode=IDEMPOTENT,可跳过SQL_SLAVE_SKIP_COUNTER,但仅限测试或容忍不一致场景 - 补完后务必比对整行:
SELECT * FROM db.t WHERE id = 12345在主从库分别执行,逐字段肉眼或脚本比对 - 特别注意时间类型精度、JSON格式空格、TEXT末尾换行——这些差异会导致后续再次触发1032











