双主必须设不同自增步长,否则两台主库用相同auto_increment_increment=1时必然生成重复主键(错误码1062),导致复制中断;应配置master1为offset=1/increment=2、master2为offset=2/increment=2。

双主多从不是“开箱即用”的高可用方案,它必须配合自增ID避让、log-slave-updates启用、GTID或position手动对齐等关键配置,否则写冲突和同步中断是大概率事件。
为什么双主必须设不同自增步长?
两台主库若都用 auto_increment_increment=1,插入新记录时极易生成相同主键,触发复制中断(错误码 1062 Duplicate entry)。这不是概率问题,是必然冲突。
-
master1配置:auto_increment_offset=1+auto_increment_increment=2 -
master2配置:auto_increment_offset=2+auto_increment_increment=2 - 重启后验证:
SHOW VARIABLES LIKE 'auto_increment%';,确保生效
log-slave-updates 必须在两台主库都开启
这是双主能“互为从库”的前提。默认情况下,从库执行的写操作不会记入自己的 binlog,导致数据无法继续向下游传播。不加这句,slave1 只能从 master1 同步,无法感知 master2 的变更,更无法参与多源复制。
- 在
my.cnf的[mysqld]段添加:log-slave-updates=ON - 该参数仅对启用了复制的实例生效,不影响纯主库场景
- 重启 MySQL 或执行
SET GLOBAL log_slave_updates = ON;(需 SUPER 权限)
从库如何同时拉取两个主库的数据?
MySQL 5.7+ 原生支持多源复制(Multi-Source Replication),但每个通道必须独立命名、独立配置,且不能共用 relay log 文件名。
- 在
slave1上分别创建两个复制通道:CHANGE MASTER TO ... FOR CHANNEL 'master1';和CHANGE MASTER TO ... FOR CHANNEL 'master2'; - 启动时指定通道:
START SLAVE FOR CHANNEL 'master1';,START SLAVE FOR CHANNEL 'master2'; - 检查状态:
SHOW SLAVE STATUS FOR CHANNEL 'master1'\G,逐个确认Slave_IO_Running和Slave_SQL_Running - 注意:两个通道的
relay_log文件名不能相同,否则会覆盖写入,建议显式配置relay_log = mysql-relay-master1和relay_log = mysql-relay-master2
GTID 能简化双主配置,但别盲目启用
GTID 确实能避免 position 错位、自动定位日志起点,但它要求所有节点 gtid_mode=ON 且 enforce_gtid_consistency=ON,而这两个参数一旦开启就不能回退——意味着你不能再执行任何不兼容 GTID 的语句(如 CREATE TEMPORARY TABLE、非事务引擎表写入等)。
- 如果业务已大量使用 MyISAM 或临时表,强行开启 GTID 会导致复制直接失败
- 双主环境下,GTID 的
gtid_executed集合需严格一致,否则START SLAVE会报错Cannot change the channel name because it is already in use - 建议先用传统 position 模式跑通,再评估 GTID 改造成本
真正难的不是配置命令敲几行,而是故障时如何判断哪条链路断了、哪个 channel 卡在什么事务、自增 ID 是否已在某台主库上越界。这些细节不提前压测和日志归档,上线后只会靠猜。











