必须成对配置auto_increment_increment和auto_increment_offset,因mysql自增值计算逻辑为next_id = max(id) + increment,且须满足(next_id - offset) % increment == 0;仅设offset不改increment时,两节点仍按默认increment=1生成1、2、3……导致主键冲突。

必须成对配置 auto_increment_increment 和 auto_increment_offset,写入 my.cnf 的 [mysqld] 段并重启 mysqld,运行时 SET GLOBAL 无效。
为什么单设 auto_increment_offset 会失效
只改 auto_increment_offset = 2 而不设 auto_increment_increment,两台节点仍按默认步长 +1 递增,都会生成 1、2、3……一同步就报 ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'。MySQL 的实际逻辑是:下一个自增值 = MAX(id) + auto_increment_increment,且必须满足 (next_id - auto_increment_offset) % auto_increment_increment == 0。offset 只影响起始点,increment 才决定间隔——二者绑定才构成完整序列规则。
双主/多主场景下怎么配参数
以双主为例,目标是 A 生成奇数、B 生成偶数,互不重叠:
- A 节点:
auto_increment_increment = 2+auto_increment_offset = 1→ 序列:1, 3, 5, … - B 节点:
auto_increment_increment = 2+auto_increment_offset = 2→ 序列:2, 4, 6, … - 三节点则设
increment = 3,offset分别为 1、2、3(注意:offset 必须在 1 到 increment 范围内,否则 MySQL 启动时静默重置为 1) - 所有节点还需确保
server-id全局唯一、log_slave_updates = ON、innodb_autoinc_lock_mode = 0,缺一不可
配置后必须校准表级 AUTO_INCREMENT 值
迁移或导入数据后,表的元数据中 AUTO_INCREMENT 值可能卡在旧偏移位置,和新步长规则冲突。例如双主 A 设了 offset = 1/increment = 2,但表当前 AUTO_INCREMENT = 100(偶数),下次插入就会撞 B 的序列。
安全做法:
- 查当前最大 ID:
SELECT MAX(id) FROM your_table - 按规则向上取整到合法值:若最大是 99,A 节点应设为 101(因为
(101 - 1) % 2 == 0) - 执行:
ALTER TABLE your_table AUTO_INCREMENT = 101 - 该操作需停写,否则并发 INSERT 可能干扰计数器
真正容易被忽略的是:配置生效与否不能只看 my.cnf 写没写对,而要连上每台节点执行 SELECT @@auto_increment_increment, @@auto_increment_offset 确认返回值;并且新建测试表插入几行,直接看 ID 是否按预期错开——纸上谈兵不如 SELECT 一行来得实在。











