迁移后自增主键“被重置”实为AUTO_INCREMENT值未正确迁移:mysqldump默认导出的ALTER TABLE AUTO_INCREMENT=语句常因--force、GUI过滤或--skip-auto-increment被跳过,导致目标库按默认值(如1)启动,插入时即报ERROR 1062;修复需先查MAX(id),再执行ALTER TABLE ... AUTO_INCREMENT=MAX(id)+1并验证。

迁移后自增主键“被重置”,其实绝大多数情况是 AUTO_INCREMENT 值没带过去,不是 MySQL 主动重置,而是目标库压根不知道该从哪继续——它按默认逻辑设成了 1 或一个极小值。
mysqldump 导出时漏掉了 AUTO_INCREMENT 注释
这是最常见原因。mysqldump 默认会在导出文件末尾加一行类似 ALTER TABLE `t` AUTO_INCREMENT = 12345; 的语句,但这个语句极易被静默跳过:
- 导入时用了
--force参数:遇到语法错误(比如注释格式异常、字符集不兼容)就跳过整行,AUTO_INCREMENT语句首当其冲 - GUI 工具(如 Navicat、DBeaver)或自研脚本做了语句过滤:只执行
CREATE和INSERT,把ALTER TABLE ... AUTO_INCREMENT当成“非核心语句”丢弃 - 导出时误加了
--skip-auto-increment,或用了--no-create-info却没手动补上ALTER语句
验证方法:用 grep "AUTO_INCREMENT=" your_dump.sql 查导出文件里有没有这行;没有就说明导出阶段就丢了。
导入后未校验 AUTO_INCREMENT 是否生效
即使导出文件里有 ALTER TABLE ... AUTO_INCREMENT = N,也不代表它真执行成功了:
- MySQL 执行
ALTER TABLE返回Query OK,不代表值已写入元数据——必须立刻执行SHOW CREATE TABLE your_table;看输出里的AUTO_INCREMENT=xxx是否等于你期望的值 - 如果表上有活跃写入,
ALTER TABLE可能被阻塞或超时(尤其大表),而客户端没捕获错误就继续后续操作 - 某些低版本客户端(如旧版 mysql CLI)在批量执行 SQL 时,对非 INSERT/UPDATE 语句的错误容忍度高,失败也不报
跨引擎或跨库迁移时机制不兼容
从 MySQL 迁到 KingbaseES、OceanBase、TiDB 等时,“自增”不是原样平移的:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- MySQL 用
AUTO_INCREMENT属性,值存在表元数据中;KingbaseES 用独立SEQUENCE对象,迁移工具若没同步last_value,序列就会从 1 开始 - MyISAM 表迁移后,在 MySQL 8.0+ 中可能因引擎差异导致重建逻辑回退(比如重启后仍按
MAX(id)+1算) - 部分分布式数据库不支持传统
AUTO_INCREMENT,改用全局唯一 ID 生成器,迁移脚本若没适配,就会硬写死id=1,2,3...导致冲突
为什么重置后插入直接报 ERROR 1062?
这不是“重置错了”,而是 AUTO_INCREMENT 值小于当前最大 id:
- 先查
SELECT MAX(id) FROM your_table;(比如得 999) - 再查
SHOW CREATE TABLE your_table;(发现AUTO_INCREMENT=500) - 此时下一条无指定
id的INSERT就会尝试插id=500→ 已存在 → 报ERROR 1062 Duplicate entry '500' for key 'PRIMARY'
真正要做的不是“防止重置”,而是迁移后立刻确认并修复:执行 ALTER TABLE your_table AUTO_INCREMENT = (SELECT COALESCE(MAX(id), 0) + 1 FROM your_table);,再 SHOW CREATE TABLE 验证。
最容易被忽略的一点:InnoDB 表即使删光数据,AUTO_INCREMENT 也不会自动回落——你看到的“重置为 1”,大概率是迁移过程漏掉了那行 ALTER,而不是数据库自己变聪明了。










