MySQL 自增主键的几个常见坑:5.7 到 8.0 的变化与避坑
【摘要】 前言自增主键(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)