Skip to content

MySQL 的自增主键并不能保证一定是连续递增的。

自增值保存在哪里?

1)MyISAM 引擎的自增值保存在数据文件中

2)MySQL 5.x 版本的InnoDB存放在内存中,所以重启,会重新计算当前表中最大的主键值作为新的自增主键值

3) MySQL 8.0 版本后,自增值的变更记录被放在了 redo log 中,提供了自增值持久化的能力 ,也就是实现了“如果发生重启,表的自增值可以根据 redo log 恢复为 MySQL 重启前的值”

使用 insert into test_pk values(null, 1, 1) 插入一行数据,再执行 show create table 命令可以看到自增值AUTO_INCREMENT会增加(显示当前最新的自增值)

在 MySQL 里面,如果字段 id 被定义为 AUTO_INCREMENT,在插入一行数据的时候,自增值的行为如下:

  • 如果插入数据时 id 字段指定为 0、null 或未指定值,那么就把这个表当前的 AUTO_INCREMENT 值填到自增字段;
  • 如果插入数据时 id 字段指定了具体的值,就直接使用语句里指定的值。
  • 自增值修改的这个操作,是在真正执行插入数据的操作之前。

自增值不连续的场景

  • 插入指定自增字段值大于当前自增值AUTO_INCREMENT+1,即跳过了一些数据
  • 插入失败
  • 插入后回滚(等价上面)
  • 批量插入:insert ... select ,mysql每次申请两倍的id,多余的会浪费掉
    • 如果是insert多组value,会计算value的数量申请足够的id,不会浪费

这里回滚不进行自增值的回滚,是因为多个事物插入的时候,自增值的回滚可能导致自增值异常 假设事务 A 申请到了 id = 1, 事务 B 申请到 id=2,那么这时候表 t 的自增值是 3,之后继续执行。这个时候 A 事物回滚如果自增值回滚会很麻烦

正在精进