自增锁锁的是“下一个可用自增值”的分配过程,而非具体行数据;不同innodb_autoinc_lock_mode控制锁粒度:0为表级锁,1为语句级锁,2为预分配无锁模式。

自增锁到底锁什么?
MySQL 的自增 ID 并不是每次 INSERT 都去表里加一个行锁,而是靠 innodb_autoinc_lock_mode 控制锁的粒度和时机。它真正锁的是“下一个可用自增值”的分配过程,不是某一行数据——所以并发插入时可能看到 ID 不连续,但不会丢 ID 或重复。
常见错误现象:Duplicate entry '123' for key 'PRIMARY' 一般不是自增锁失效,而是手动 INSERT 了已存在的 ID,或者用了 REPLACE INTO / INSERT ... ON DUPLICATE KEY UPDATE 触发了主键冲突。
- 普通 INSERT(不含显式指定 ID):走轻量级的 mutex,不持表级锁
- INSERT ... SELECT、LOAD DATA、带明确值的批量 INSERT:在
innodb_autoinc_lock_mode = 0下会持表级AUTO_INC锁,直到语句结束 -
innodb_autoinc_lock_mode = 2(默认)下,这类语句只在分配阶段短暂加锁,后续插入用预分配的 ID 段,性能高但可能跳号
三种 lock_mode 怎么选?
关键看你的写入模式是否容忍 ID 跳号,以及有没有混合使用“显式指定 ID”和“依赖自增”的语句。
场景判断比参数名更重要:innodb_autoinc_lock_mode = 0(传统锁)适合老应用、逻辑强依赖连续 ID 的场景,但并发写入吞吐低;= 1(交错锁)是大多数 OLTP 的平衡点;= 2(无锁预分配)适合高并发导入、分库分表中间件生成全局 ID 的辅助场景。
- 如果用
mysqldump --single-transaction导出再导入,且目标库innodb_autoinc_lock_mode = 2,导入时可能因预分配导致 ID 比源库大一截——这不是 bug,是设计行为 - 混合写法危险:
INSERT INTO t VALUES (100, 'a'), (NULL, 'b');中的NULL会触发自增分配,但具体值取决于当前锁模式和执行时序,容易在mode=2下和别的连接冲突 - 变更该参数需重启 MySQL,且必须确保所有节点配置一致(尤其主从或 MGR 环境)
为什么 SHOW CREATE TABLE 看不到自增锁设置?
SHOW CREATE TABLE 只反映表结构定义,而 innodb_autoinc_lock_mode 是全局服务级参数,存于内存中,不持久化到表元数据。你查 SELECT @@innodb_autoinc_lock_mode; 才能确认实际生效值。
容易踩的坑:以为改了 my.cnf 就立刻生效,其实必须重启;或者在 Docker 容器里改了配置文件但没重建容器,导致 SELECT @@... 返回还是旧值。
- 检查命令:
SELECT @@global.innodb_autoinc_lock_mode; - 临时修改(不推荐生产用):
SET GLOBAL innodb_autoinc_lock_mode = 1;—— 但某些版本会拒绝运行时修改 - Percona Server 和 MySQL 8.0+ 支持动态修改,MariaDB 则完全不支持运行时调整
insert select 为啥卡住其他 insert?
当 innodb_autoinc_lock_mode = 0 或 = 1 时,INSERT INTO t1 SELECT * FROM t2 这类语句会持有 AUTO_INC 表级锁,直到整个语句执行完。期间所有其他需要分配新自增 ID 的 INSERT(哪怕只插一行)都会被阻塞。
这不是死锁,是设计上的串行化保障。如果你发现监控里 innodb_row_lock_waits 暴涨,同时慢日志里频繁出现长耗时的 INSERT ... SELECT,大概率就是它在拖后腿。
- 优化方向:拆成小批量
LIMIT循环插入,避免单语句扫全表 - 更彻底的解法:把
innodb_autoinc_lock_mode改成2,但要同步评估下游 binlog 解析、闪回工具、审计系统是否兼容跳号 - 注意:
INSERT IGNORE或ON DUPLICATE KEY UPDATE在mode=2下仍可能因唯一键冲突重试多次,间接放大分配不确定性
自增锁的复杂性不在语法,而在它横跨了存储引擎、复制协议、备份恢复多个层面。最常被忽略的是:binlog 格式(STATEMENT vs ROW)会改变自增值在从库的生成方式,而这个细节和 innodb_autoinc_lock_mode 共同决定最终一致性。











