增量迁移时自增主键冲突的根本原因是目标表AUTO_INCREMENT值未同步至已导入数据的最大id,每次增量前必须校准MAX(id)与AUTO_INCREMENT,且ALTER TABLE AUTO_INCREMENT=N须设为MAX(id)+1并确保在InnoDB上执行。

增量迁移时自增主键冲突,本质是目标表的 AUTO_INCREMENT 值没跟上已导入数据的最大 id,只要在每次增量前校准一次,基本不会触发 ERROR 1062。
增量前必须查清两个值:MAX(id) 和 AUTO_INCREMENT
很多人只在全量迁移时校验一次,增量阶段就不管了,结果第二轮增量一插就报错。原因很简单:上一轮增量可能插入了新记录,MAX(id) 已变,但 AUTO_INCREMENT 还卡在旧值。
- 执行
SELECT MAX(id) FROM your_table;获取当前最大 ID - 执行
SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA='your_db' AND TABLE_NAME='your_table';查当前自增值 - 只要
AUTO_INCREMENT≤MAX(id),下一条无显式id的INSERT必然冲突 - 别依赖“上次设过就没事”——每次增量前都得重查
ALTER TABLE ... AUTO_INCREMENT = N 怎么设才真正生效
这个语句不是“设完就跑”,它只影响下一次未指定主键的插入,且对 MyISAM 表不可靠、对大表会锁死写入。
-
N必须严格大于MAX(id),推荐直接设为MAX(id) + 1(不是 +0,也不是随便填个大数) - 仅 InnoDB 表可靠;MyISAM 表重启后可能重置,线上环境别用
- 执行时加表级写锁,千万避开高峰;大表建议配合
pt-online-schema-change - 它不改已有数据,只改后续生成逻辑——所以设错也不会损坏数据,但会继续撞
增量同步工具自带的自增处理陷阱
像 mysqldump --single-transaction 或 mydumper 导出时,默认会把 AUTO_INCREMENT 值写进 SQL 文件末尾,但这个语句极易被跳过。
- 导入时用了
--force参数,遇到前面语法错误就会忽略后面所有语句,包括ALTER TABLE ... AUTO_INCREMENT=... - 某些 ORM 或迁移脚本会自动过滤
ALTER类语句(防误操作),导致该行根本没执行 - 检查方法:打开导出 SQL 文件,搜索
AUTO_INCREMENT=,确认存在且未被注释 - 更稳妥的做法:增量前手动执行一次
ALTER TABLE your_table AUTO_INCREMENT = ?,别依赖导出文件
主从架构下增量迁移的偏移风险
如果目标库是主从结构,且从库参与了增量写入(比如双写或灰度),AUTO_INCREMENT 可能已在从库上提前增长,但主库还没同步过去,导致后续主库写入时 ID 重叠。
- 不要只查主库的
MAX(id)和AUTO_INCREMENT,从库也得查——尤其当从库开写权限时 - 发现从库
AUTO_INCREMENT小于主库,不能直接ALTER,得配合auto_increment_offset和auto_increment_increment调整生成规则 - GTID 模式下缓解明显,但跨库合并、多源复制等场景仍需人工核对各节点的
MAX(id)范围 - 最省事的预防:增量期间从库设
read_only = ON,确保所有写只走主库
真正容易被忽略的不是怎么修,而是“谁在写、从哪读、ID 从哪来”这三件事没对齐——哪怕只漏查一个从库,或者忘了某次增量插入了 10 条记录,AUTO_INCREMENT 就会错位。校准不是一次性动作,是每次增量前的必检项。


















