主从复制冲突的本质是啥
MySQL 主从复制本身不解决冲突,它只是单向同步:从库被动执行主库的 binlog。所谓“冲突”,其实是从库上已有数据与主库发来的写操作不兼容,比如
INSERT主键重复、
UPDATE影响 0 行、
DELETE找不到记录等。这些在从库报错后会直接中断 SQL 线程(
Seconds_Behind_Master变为
NULL),不是“自动处理”,而是“卡住等你修”。
常见冲突类型及对应跳过策略
不能一概用“跳过错误”,得看场景:
主键/唯一键冲突(1062 错误):主库插入一条记录,但从库已存在同主键值(比如从库被手动写入过)。此时可临时跳过:SET GLOBAL sql_slave_skip_counter = 1;(仅适用于
STATEMENT格式);更安全的是用
gtid_next跳过单个 GTID:
SET gtid_next='xxx-xxx-xxx:12345'; BEGIN; COMMIT; SET gtid_next='AUTOMATIC';找不到记录(1032 错误):主库执行了
UPDATE或
DELETE,但从库该行不存在。原因常是主库删了又插,或从库被误删。跳过前建议先查
SHOW SLAVE STATUS\G的
Exec_Master_Log_Pos和
Relay_Log_File,确认上下文再决定跳还是补数据。 表结构不一致导致的执行失败:比如从库少一个字段,主库却往里插值。这种不能跳过,必须先对齐表结构(
ALTER TABLE),否则后续所有涉及该列的操作都会持续报错。
避免冲突比修复更重要
很多冲突其实源于架构或运维疏漏:
从库禁止写入:确保read_only=ON(注意:超级用户仍可写,必要时加
super_read_only=ON) 主库避免非确定性语句:如
INSERT ... SELECT没带
ORDER BY,或用了
NOW()、
UUID()等函数,在
STATEMENT复制模式下会导致主从数据不一致 慎用
auto-increment:多主或分片场景下,若未配置
auto_increment_offset和
auto_increment_increment,极易出现主键冲突 监控要盯紧
Seconds_Behind_Master和
Slave_SQL_Running_State,一旦变成
NULL或
Waiting for master to send event后长期不动,大概率已出错
GTID 模式下处理冲突更可控但门槛更高
开启
gtid_mode=ON后,每个事务有唯一 ID,跳过指定事务比靠偏移量更精准。但要注意: 所有节点必须统一开启 GTID,且
enforce_gtid_consistency=ON,否则启动失败 跳过事务必须在从库停掉复制后操作:
STOP SLAVE;→
SET gtid_next='xxx:yyy';→
BEGIN; COMMIT;→
SET gtid_next='AUTOMATIC';→
START SLAVE;如果主库已删除某个 GTID 对应的 binlog(比如 purge 过早),从库重连时可能因找不到日志而无法继续,这时得考虑重建从库 真正麻烦的不是怎么跳过一次错误,而是为什么会出现那个错误——是人为写了从库?是应用没走主库?还是 binlog 格式和业务逻辑不匹配?查清源头,比记住跳过命令重要得多。
