MySQL 自增主键的几个常见坑:5.7 到 8.0 的变化与避坑

举报
yd_282022914 发表于 2026/10/24 07:57:13 2026/10/24
【摘要】 前言自增主键(AUTO_INCREMENT)几乎是每个 MySQL 表的默认选择,但它的行为并不总是"按预期连续递增"。这篇文章梳理几个高频踩坑点,以及 MySQL 8.0 做了哪些改进。坑一:自增 id 为什么会不连续?最常见的误解是"自增列一定连续递增"。实际上,事务回滚、唯一键冲突、批量插入失败都会导致已经分配的自增值被浪费,下一条记录不会复用它。这是设计取舍——为了避免并发插入时的锁...

前言

自增主键(AUTO_INCREMENT)几乎是每个 MySQL 表的默认选择,但它的行为并不总是"按预期连续递增"。这篇文章梳理几个高频踩坑点,以及 MySQL 8.0 做了哪些改进。

坑一:自增 id 为什么会不连续?

最常见的误解是"自增列一定连续递增"。实际上,事务回滚、唯一键冲突、批量插入失败都会导致已经分配的自增值被浪费,下一条记录不会复用它。这是设计取舍——为了避免并发插入时的锁竞争,自增计数器只保证递增,不保证连续。

坑二:不同隔离模式下的自增锁

innodb_autoinc_lock_mode 有三种模式:0(traditional)语句级表锁;1(consecutive,5.7 默认)简单 INSERT 提前释放,批量 INSERT 仍锁到语句结束;2(interleaved)每次申请立即释放,并发最高,配合 row 格式 binlog 在 8.0 下复制安全。

坑三:8.0 之前自增计数器重启会回退

5.7 及更早版本自增计数器只存在内存,重启后重新取 MAX(id)+1,删过大 id 后重启可能与历史记录冲突。8.0 把自增计数器写入 redo log 持久化,重启后不再回退。

坑四:多写架构要错开自增起点

多主/双写场景两个节点都从 1 开始会主键冲突。设置 auto_increment_increment(步长)和 auto_increment_offset(起点),让节点 1 生成奇数、节点 2 生成偶数。

坑五:别用 INT 当自增主键

INT 无符号上限约 42.9 亿,增长快的表容易撞顶。新表直接用 BIGINT UNSIGNED,省去后期改主键的痛苦。

小结

  • 自增只保证递增不保证连续,不要拿它做业务序号;
  • 升级 8.0 后自增持久化、并发锁更轻;
  • 多主架构务必配 increment/offset;
  • 新表主键直接 BIGINT。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。