自增主键耗尽后不触发新锁,但会加剧AUTO-INC锁竞争:当ID达上限(如4294967295)时,InnoDB停止递增,所有插入尝试分配同一值,导致线程反复碰撞、重试;INSERT ... ON DUPLICATE KEY UPDATE仍申请自增锁,每执行一次即引发冲突检测+回滚+重试循环,使CPU和锁等待飙升;ERROR 1062出现即表明计数器已停摆,此时应优先扩容主键类型(如改为BIGINT UNSIGNED),而非调整锁参数。

自增主键耗尽后不会触发新锁,但会放大已有锁竞争
主键耗尽本身不产生新锁,但会让原本可容忍的自增锁争用瞬间变成瓶颈。当 AUTO_INCREMENT 值卡在上限(如 4294967295)时,InnoDB 不再递增,所有新插入都尝试分配同一个 ID 值——这导致大量线程在获取自增值阶段反复碰撞、重试、失败,表现为 AUTO-INC lock 持续被抢占,而非真正“持有”。
为什么 INSERT ... ON DUPLICATE KEY UPDATE 会雪上加霜
这类语句仍会申请自增锁,哪怕最终没插入新行。主键耗尽后,它每执行一次,就触发一次冲突检测 + 回滚 + 锁释放 + 重试循环,CPU 和锁等待时间飙升。常见现象包括:
-
SHOW ENGINE INNODB STATUS中频繁出现waiting for auto-inc lock on xxx - 慢查询日志里同一条
INSERT ... ON DUPLICATE KEY UPDATE执行时间从几毫秒涨到数百毫秒 - 监控显示
innodb_row_lock_waits没变,但innodb_autoinc_locks计数暴增
innodb_autoinc_lock_mode 在耗尽场景下的实际表现差异
模式 0 和 1 都会卡住,模式 2 看似“无锁”,实则更危险:
- 模式 0(传统表锁):整条
INSERT语句期间锁表,耗尽后所有插入串行排队,错误集中爆发 - 模式 1(默认):单行插入只争抢 mutex,但失败重试频率高,mutex 竞争激烈,
show status like 'Innodb_mutex_os_wait%'可见明显升高 - 模式 2(无锁):不加锁,但每次失败都生成新事务 ID 并写 binlog,主从复制可能因重复事件报错
ERROR 1062,且无法回退已分配的 ID
真正该盯住的不是锁,而是错误日志里的那个数字
只要看到 ERROR 1062 (23000): Duplicate entry '4294967295' for key 'PRIMARY',说明自增计数器已经停摆。此时任何锁优化都治标不治本——因为问题根源是 ID 分配器失效,不是并发太高。修复顺序必须是:
- 立刻停写或切只读,防止更多失败事务消耗连接和资源
- 查
SELECT MAX(id)和SHOW TABLE STATUS确认是否真耗尽 - 若确认耗尽,优先走
ALTER TABLE ... MODIFY id BIGINT UNSIGNED路径,别试图调innodb_autoinc_lock_mode或重置AUTO_INCREMENT
锁参数调得再细,也救不回一个已经卡死的计数器。


















