auto_increment_increment 和 auto_increment_offset 必须成对配置且重启生效,increment 决定步长、offset 决定起始偏移,多节点需保证 offset 互异且在 1 到 increment 范围内,并人工对齐现有表 auto_increment 值以避免冲突。

auto_increment_increment 和 auto_increment_offset 必须成对设,缺一不可
只改 auto_increment_offset 不动 auto_increment_increment,等于白配。比如 A 节点设了 auto_increment_offset = 2,但 auto_increment_increment 还是默认的 1,那它照样生成 1、2、3……和 B 节点完全重叠。
真正起作用的是组合逻辑:auto_increment_increment 决定“跳多远”,auto_increment_offset 决定“从哪开始”。两节点必须设为: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 - offset 只能取 1 到 increment 之间的整数,且各节点不能重复
- 这个规则只约束新插入的自增 ID,不影响已有数据
配置必须写进 my.cnf 的 [mysqld] 段并重启 mysqld
SET GLOBAL auto_increment_increment = 2 这类命令只是临时生效,MySQL 重启后立刻回滚到配置文件值或默认值。双主切主时若参数丢失,新主库用默认步长 +1 插入,马上撞 ID。
正确做法是编辑 /etc/my.cnf 或 /etc/mysql/my.cnf,在 [mysqld] 下添加:
auto_increment_increment = 2 auto_increment_offset = 1
A 节点如此,B 节点把 offset 改成 2。注意:
- 不能写到
[client]或[mysql]段,否则不加载 - MySQL 8.0+ 虽支持
SET PERSIST,但不同版本行为不一致,生产环境优先走配置文件 - 确认没有被
!include或环境变量覆盖掉配置
验证是否真生效,不能只看配置文件
改完配置、重启服务后,必须连上每台实例执行 SQL 查运行时值:
SELECT @@auto_increment_increment, @@auto_increment_offset;
返回结果必须严格匹配规划(如 A 是 2/1,B 是 2/2)。再建测试表验证:
CREATE TABLE test_inc (id INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
A 上执行三次 INSERT INTO test_inc VALUES (),(),();,查出来应该是 1,3,5;B 上同样操作应得 2,4,6。如果出现 1,2,3,说明配置没生效,大概率是段落写错或没重启。
已有表的最大 ID 必须与未来序列不重叠
配置只影响后续插入,不调整现有数据。如果 A 当前最大 ID 是 99,它下次会插 101(因为 99+2=101),没问题;但如果 B 当前最大 ID 是 100,它下次插 102,也安全。但若某台机器当前最大 ID 是 101,而它的 offset 是 2、increment 是 2,下一个值是 102 —— 看似没问题,可万一另一台机器刚插了 102,就撞了。
所以加节点前必须人工对齐:
- 查出每台机器所有带自增主键的表的
MAX(id) - 按规划算出每台机器下一个合法 ID(例如 offset=1, increment=2 → 下一个是大于当前 MAX 的最小奇数)
- 对每张表执行
ALTER TABLE tbl AUTO_INCREMENT = N,N 设为算出的值
漏掉任意一张表,上线后就可能主键冲突,错误信息通常是 ERROR 1062 (23000): Duplicate entry 'X' for key 'PRIMARY'。











