mysql主从复制如何处理数据冲突_mysql同步策略解析

来源:这里教程网 时间:2026-02-28 20:45:56 作者:

主键冲突(ERROR 1062)怎么快速定位和修复

主键或唯一键冲突是最常见的复制中断原因,典型错误是

ERROR 1062 (23000): Duplicate entry '1001' for key 'PRIMARY'
。它说明从库试图插入一条主库已存在、且从库本地也已存在的记录——通常是因为人为在从库执行过
INSERT
,或双主配置下自增ID未错开。

定位时直接看

SHOW SLAVE STATUS\G
中的
Last_SQL_Error
Relay_Log_File
+
Relay_Log_Pos
,再用
mysqlbinlog --base64-output=DECODE-ROWS -v
解析中继日志,确认那条“撞车”的 INSERT 是什么内容。

若该行确实不该存在(比如测试数据),直接在从库
DELETE FROM table_name WHERE id = 1001
,再
START SLAVE
若想保留从库数据、跳过冲突事件:启用 GTID 时用
SET GTID_NEXT='xxx:yyy'; BEGIN; COMMIT;
;非 GTID 模式用
SET GLOBAL sql_slave_skip_counter = 1
(仅跳一个事件)
严禁在生产环境长期开启
slave-skip-errors = 1062
,它会掩盖问题,导致主从静默不一致

记录不存在(ERROR 1032)为什么比主键冲突更危险

ERROR 1032 (HY000): Can't find record in 't_user'
表示主库执行了
UPDATE
DELETE
,但从库找不到对应行。表面看只是“跳过”,实则暴露了更深层的数据漂移:可能从库被删过数据、或主库之前没同步成功就跳过了、甚至 binlog 被截断过。

这类错误不能简单跳过,否则后续依赖该行的变更(如级联更新、触发器逻辑)全会失效。

先查
Exec_Master_Log_Pos
对应的主库 binlog,确认原始 SQL 是什么;再查从库是否真缺失这行(
SELECT * FROM t_user WHERE id = xxx
若确认缺失且业务允许,可从主库导出该行:
mysqldump --where="id=xxx" db table > row.sql
,再导入从库
工具推荐
pt-slave-repair
:它会自动解析 binlog,对
DELETE
直接跳过,对
UPDATE
则转成
REPLACE INTO
反向修复——但要求
binlog_format = ROW
binlog_row_image = FULL

GTID 模式下跳过事务为什么必须用空事务注入

启用了

gtid_mode=ON
后,
sql_slave_skip_counter
就失效了,因为 GTID 复制靠事务 ID 推进,不是靠日志位置计数。强行设 skip counter 会导致 GTID 集合错乱,后续同步彻底失败。

正确做法是“伪造已执行”:把报错事务的 GTID(见

Retrieved_Gtid_Set
Executed_Gtid_Set
中带错误的那个)赋给
GTID_NEXT
,再提交一个空事务。

操作顺序必须严格:
STOP SLAVE
SET GTID_NEXT='uuid:12345'
BEGIN; COMMIT;
SET GTID_NEXT='AUTOMATIC'
START SLAVE
注意:如果
GTID_NEXT
值写错(比如少一位、大小写混),会报
ERROR 1840
,必须重试
不要在多线程复制(
slave_parallel_workers > 0
)时注入,先
SET GLOBAL slave_parallel_workers = 0
再操作

read_only 和 super_read_only 哪个才真正防住误写

read_only = ON
只阻止普通用户写入,但拥有
SUPER
权限的账号(如运维账号、监控账号、备份工具)仍能绕过。一旦这类账号连上从库执行了 DML,冲突就埋下了。

真正有效的防护是

super_read_only = ON
(MySQL 5.7.8+),它连
SUPER
权限都限制了——除非先关掉它,否则任何写操作都会报
ERROR 1290

配置后务必验证:
mysql -uadmin -p -e "INSERT INTO test.t VALUES(1)"
应失败;再用
SET GLOBAL super_read_only = OFF
测试是否可临时放开
别忘了在 my.cnf 里持久化:
super_read_only = ON
,避免重启后失效
如果应用本身有高权限连接池,建议同时回收其
SUPER
权限,只留
SELECT, REPLICATION CLIENT
等必要权限

最常被忽略的一点:冲突处理不是“修完就完”,而是要反推根源。比如一次

1062
错误背后,可能是中间件路由错误、应用配置漏切读写分离、或是 DBA 手动修复时没走标准流程。修复动作本身越快,越要花时间确认“为什么这里会写从库”。

相关推荐