必须成对设置auto_increment_increment和auto_increment_offset,仅改其一将导致双主主键冲突;二者需同设global级、重启不丢失,且offset∈[1,increment],配合server_id、binlog等配置方可实现可靠双主。

auto_increment_increment 和 auto_increment_offset 必须成对设置
只改 auto_increment_increment 不调 auto_increment_offset,或者反过来,都会导致双主写入时主键重复。MySQL 的自增逻辑不是简单“加步长”,而是基于当前表最大 ID、auto_increment_offset 和 auto_increment_increment 共同计算下一条 ID;两台机器必须用相同 increment、不同 offset,且 offset 值必须落在 [1, increment] 范围内。
- 双主场景:固定设
auto_increment_increment = 2,A 设auto_increment_offset = 1(生成 1、3、5…),B 设auto_increment_offset = 2(生成 2、4、6…) - 三主则
auto_increment_increment = 3,offset 分别为1、2、3 - 不要用 SET GLOBAL 动态设置:重启后失效,且 MySQL 8.0.33+ 会忽略会话级设置对新建表的影响
server_id 和 binlog 配置缺一不可
仅设自增参数,同步仍会失败。双主依赖 binlog 复制,而复制要求每个节点有唯一 server_id,且必须开启 binlog 并配置格式。
-
server_id必须是纯数字(如101),不能是 IP 或主机名(如mysql-master1) -
log-bin路径需确保目录存在且 MySQL 进程有写权限(常见坑:/var/lib/mysql/mysql-bin目录无写权限) -
binlog_format推荐ROW;STATEMENT在含函数、临时表等语句下极易主从不一致
log-slave-updates 必须开启
这是实现“双向复制”的关键开关。它让从库在执行完同步来的事件后,也把该事件写入自己的 binlog,从而允许 A ← B ← A 的环形链路成立。
- 若未启用,B 收到 A 的变更后不会记录到自身 binlog,A 就无法再从 B 同步回这条数据
- 配置项名是
log-slave-updates(注意连字符),不是log_slave_updates或其他变体 - 必须在
[mysqld]段落中静态配置,与server_id、auto<em>increment</em>*等一同生效
已有数据的表不会自动重排 ID
配置生效只影响后续 INSERT,不会重排现有记录的主键。如果双主搭建前表里已有 ID = 1~100 的数据,那么即使设置了 offset = 1/increment = 2,下一条插入也未必是 101——它取决于当前 MAX(id) 和内部初始化逻辑。
- 重启 MySQL 后可能出现“跳变”现象(比如上次是 7,重启后变成 9 或 10),因为
offset参与启动时的自增初始值推导 - 如果已有数据 ID 已覆盖全部奇偶序列(例如 A 和 B 都已各自插入过 ID),上线前应人工校验或清空测试表,避免首次 INSERT 就撞 ID
最易被忽略的是:所有这些参数都必须写进 my.cnf 的 [mysqld] 段,并重启 mysqld 才真正生效;任何漏配或错配,都会让双主在某次 INSERT 后突然报 Duplicate entry 'X' for key 'PRIMARY'。











