ERROR 1062主键冲突表明AUTO_INCREMENT未对齐实际最大ID;须先查MAX(id)和information_schema中AUTO_INCREMENT值,若前者≥后者,则执行ALTER TABLE AUTO_INCREMENT=MAX(id)+1校准。

迁移后插入新记录报 ERROR 1062 主键冲突
这是最典型的信号:新库的 AUTO_INCREMENT 值没对齐实际数据最大 ID。比如 SELECT MAX(id) FROM users 返回 987,但 SHOW CREATE TABLE users 显示 AUTO_INCREMENT=500——下一次 INSERT 就会试图用 500,而该 ID 已存在,直接报错。
根本原因不是命令漏了,而是迁移工具(如 mysqldump)导出时没带 AUTO_INCREMENT 注释,或导入时跳过了末尾的 ALTER TABLE ... AUTO_INCREMENT=... 语句。
- 先确认错位:查两处值是否匹配:
SELECT COALESCE(MAX(id), 0) FROM users和SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA='your_db' AND TABLE_NAME='users' - 若前者 > 后者,必须立刻重置,否则无法写入新数据
- 若后者远大于前者(比如
MAX(id)=100,但AUTO_INCREMENT=100000),虽不报错,但 ID 空洞大,可能暴露业务量或影响分页逻辑
用 ALTER TABLE 安全重置为 MAX(id)+1
只要表没被并发写入,这条语句就是修复核心操作。它不删数据、不锁表太久,只修正元数据里的计数器起点。
执行前务必停写或选低峰期,因为 ALTER TABLE 会加 MDL 锁,阻塞后续 INSERT/UPDATE。
- 先查当前最大 ID:
SELECT COALESCE(MAX(id), 0) FROM users(COALESCE防空表返回 NULL) - 假设计算结果是
12345,就执行:ALTER TABLE users AUTO_INCREMENT = 12346 - 别设成
12345或更小——MySQL 会静默修正为12346,白跑一趟 - 执行后立刻验证:
SHOW CREATE TABLE users,确认输出里AUTO_INCREMENT=12346已生效
mysqldump 导出时必须保留 AUTO_INCREMENT 注释
默认行为其实就对了,但很多人加了 --skip-auto-increment 或手动删了 dump 文件末尾的 ALTER TABLE 行,导致迁移后“失忆”。
mysqldump 默认会在每个表的 CREATE TABLE 语句后补一行类似 ALTER TABLE `users` AUTO_INCREMENT=12346; 的语句,这就是迁移保活的关键。
- 导出时不加任何跳过自增的参数:
mysqldump -u root your_db > backup.sql - 导入前扫一眼 SQL 文件末尾,确认有
ALTER TABLE ... AUTO_INCREMENT=...行,并且数值合理 - 如果用程序做增量迁移(如 INSERT SELECT),记得显式读取源表
AUTO_INCREMENT值,再在目标表执行对应ALTER
TRUNCATE 不适用于迁移后修复
别看到“重置”就本能想 TRUNCATE——它清空数据,而迁移后你手里的数据是刚导进来的,不能删。
TRUNCATE 只适合“重建空库”场景,比如测试环境初始化;生产迁移后已有完整数据,此时唯一合法动作是校准计数器,不是清零。
真正容易被忽略的是:InnoDB 在重启后会扫描全表重算 AUTO_INCREMENT,但仅限于没执行过 ALTER TABLE ... AUTO_INCREMENT=N 的表。一旦你手动设过,这个值就固化在表元数据里,重启也不变。所以迁移后不检查、不重置,下次 MySQL 重启,问题照旧。


















