1062错误需先查show slave status\g确认last_sql_error,区分主库重复插入或从库误写;rbr模式下须用mysqlbinlog解析relay log定位冲突行;优先delete从库多余数据而非跳过事务,gtid模式下跳过需set gtid_next后空事务提交。

查Last_SQL_Error确认是1062错误
看到Slave_SQL_Running: No,第一件事不是停启复制,而是执行SHOW SLAVE STATUS\G,直接盯住Last_SQL_Error字段。如果报错里有Duplicate entry和Error_code: 1062,基本能确定是主键冲突——但得进一步区分:是主库真插入了重复值,还是从库被误写过?
- 1062在RBR模式下常伴随
at master log mysql-bin.xxxxxx, end_log_pos NNNN,看不到SQL本身,必须解析relay log才能确认操作对象 - 别只看错误里的表名和ID,有些应用用复合主键或UUID,
Duplicate entry '10086' for key 'PRIMARY'里的10086未必是自增ID,可能是业务字段拼接值 - 如果
Last_SQL_Error还带on query: INSERT INTO ...(即显示完整语句),大概率是SBR模式,或MySQL版本较老;新版RBR极少这样输出
用mysqlbinlog解析relay log定位具体行
RBR模式下,光看Last_SQL_Error只能知道位置,不知道哪张表、哪一行冲突。必须用mysqlbinlog读取从库本地的relay log文件,还原出真实变更。
- 先用
ls /var/lib/mysql/*relay*确认relay log真实路径(Docker环境常带主机名前缀,如mysql-relay-bin-abc123.000001) - 根据
end_log_pos前后各偏移50–100字节解析:mysqlbinlog --base64-output=decode-rows -v --start-position=123400 --stop-position=123500 /var/lib/mysql/relay-log.000001 - 重点找
### INSERT INTO `db`.`table`和### SET @1=... @2=...段,比对@1(通常是主键)是否与从库现存记录冲突 - 如果解析出的INSERT在从库手动执行也报1062,说明冲突行已存在;如果执行不报错,那问题可能出在触发器、外键或分区表逻辑上
优先DELETE冲突行,而不是跳过事务
SET GLOBAL sql_slave_skip_counter = 1在RBR下极危险:它跳过的不是一条语句,而是一个事务里的若干行事件,容易导致部分更新、半截脏数据。对1062,更安全的做法是清理从库侧的“多余”数据。
- 执行
SELECT * FROM table WHERE primary_key = X(X取自### SET @1=X),确认该行是否本不该存在 - 如果该行是运维误操作写入(比如手动INSERT测试数据),直接
DELETE FROM table WHERE primary_key = X,再START SLAVE - 如果该行是历史残留、但业务上应存在(比如主库删过又重插),需同步检查主库binlog中对应时间点是否有DELETE,避免误删有效数据
- 若表无主键或用UUID,冲突可能源于并发写入,此时应补主键+监控从库
read_only=ON,防止人为写入
跳过事务仅限紧急止血,且必须用GTID方式
当冲突行无法简单DELETE(比如涉及外键级联、或业务逻辑复杂),且必须快速恢复复制时,跳过是最后手段。但sql_slave_skip_counter在GTID模式下已失效,强行使用会报错Cannot use sql_slave_skip_counter when @@GLOBAL.GTID_MODE = ON。
- 先STOP SLAVE,然后从
Last_SQL_Error里提取GTID,形如f8e7f9b2-1a3c-11ef-8a12-00155d012345:12345 - 执行:
SET GTID_NEXT='f8e7f9b2-1a3c-11ef-8a12-00155d012345:12345'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; START SLAVE; - 跳过后立刻
SHOW SLAVE STATUS\G确认Exec_Master_Log_Pos推进、Seconds_Behind_Master开始下降 - 跳过不等于修复:务必记录该GTID,后续用
pt-table-checksum或mysqldiff校验主从一致性,尤其关注该事务涉及的表
真正麻烦的从来不是1062这个错误码,而是你不确定那条“冲突”的数据,到底是该留、该删、还是该从主库反向同步过来。很多线上事故,都是跳过之后发现下游报表少了一天订单,才意识到那个“重复插入”其实是补偿逻辑的一部分。











