mysql双master同步需确保server-id全局唯一、自增id错开、复制用户权限精准、写入严格单边隔离;否则将因id冲突、主键重复、权限或日志位置错误导致同步中断。

主库ID冲突导致同步中断
MySQL双Master最常崩在server-id相同或未设——两个实例用同一个ID,从库会拒绝接收对方的binlog,报错Got fatal error 1236 from master。必须确保每个节点的server-id是全局唯一的整数,比如A设为1,B设为2,不能是1和1,也不能是0(MySQL会自动转成1,等同于重复)。
实操建议:
- 修改
/etc/my.cnf,在[mysqld]下分别写死server-id=1和server-id=2,重启前确认无语法错误 - 改完后连上MySQL执行
SELECT @@server_id;验证,别只信配置文件 - 如果已启用了GTID,
server-id仍需唯一,但GTID本身能避免部分位置点冲突,不是免检金牌
自增ID重复引发主键冲突
双Master默认都允许写入,AUTO_INCREMENT字段若不协调,两边同时INSERT就会撞出Duplicate entry '5' for key 'PRIMARY'。这不是同步延迟问题,是设计缺陷。
实操建议:
- 在A节点设
auto_increment_offset=1、auto_increment_increment=2 - 在B节点设
auto_increment_offset=2、auto_increment_increment=2 - 这样A生成1、3、5…,B生成2、4、6…,天然错开
- 注意:该设置对已有表无效,只影响新插入;如果表里已存在自增ID重叠,先人工清理或重置
AUTO_INCREMENT值
同步线程启动失败的典型原因
执行START SLAVE;后查SHOW SLAVE STATUS\G,发现Slave_IO_Running: No或Slave_SQL_Running: No,常见不是密码错,而是权限或日志位置不对。
实操建议:
- 创建复制用户时,必须用
REPLICATION SLAVE权限,且host不能写%(尤其当有IPv6或DNS解析异常时),建议明确指定对方IP - 执行
CHANGE MASTER TO前,先在对方执行SHOW MASTER STATUS;取准确的File和Position,别凭记忆或旧快照填 - 如果之前同步断过,又手动改过数据,
SQL thread可能卡在某条语句,此时SET GLOBAL sql_slave_skip_counter = 1;只是临时绕过,治标不治本,得先定位冲突语句再处理
写操作必须严格分离到单边
双Master不是高可用读写分离方案,它本质是“双写+双向同步”,一旦应用层没控制好写入路由,两边同时更新同一行,必然触发主键/唯一键冲突,同步直接停摆。
实操建议:
- 上线前必须在应用层做写节点硬隔离:比如按业务模块划分,订单写A,用户写B;或按时间切片,白天写A,晚上写B(需配套运维切换流程)
- 禁止在任意节点执行
INSERT ... ON DUPLICATE KEY UPDATE或REPLACE INTO,这类语句在另一端重放时行为不可控 - 监控必须覆盖
Seconds_Behind_Master和Slave_SQL_Running_State,光看线程是否Running不够,要盯住实际执行状态
主主互备看着简单,真正稳住靠的是写入路径的绝对收敛和自增规则的机械对齐——配置只是骨架,约束才是血肉。漏掉任意一个点,不出三天就收到告警。











