暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MYSQL-NOTE31,自增主键

原创 Oracle 2023-07-01
91


自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,因此索引更紧凑。但是自增主键不能保证连续递增

 

show create table 命令可以看到下一次自增主键的的id,会误以为自增主键保存在表结构里面。实际上,表的结构定义存放在后缀名为.frm 的文件中,但是并不会保存自增值

 

在 MySQL 5.7 及之前的版本,自增值保存在内存里,并没有持久化。每次重启后,第一次打开表的时候,都会去找自增值的最大值 max(id),然后将 max(id)+1 作为这个表当前的自增值。

MySQL 8.0 版本,将自增值的变更记录在了 redo log 中,重启的时候依靠 redo log 恢复重启之前的值。

 

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

1)如果插入数据时 id 字段指定为 0、null 或未指定值,那么就把这个表当前的 AUTO_INCREMENT 值填到自增字段;

2)如果插入数据时 id 字段指定了具体的值,就直接使用语句里指定的值。

 

自增值生成算法是:从 auto_increment_offset 开始,以 auto_increment_increment 为步长,持续叠加,直到找到第一个大于 X 的值,作为新的自增值。其中,auto_increment_offset 和 auto_increment_increment 是两个系统参数,分别用来表示自增的初始值和步长,默认值都是 1。

 

双 M 的主备结构里要求双写的时候,我们就可能会设置成 auto_increment_increment=2,让一个库的自增 id 都是奇数,另一个库的自增 id 都是偶数,避免两个库生成的主键发生冲突

 

唯一键冲突是导致自增主键 id 不连续:

这自增值生成是在真正执行插入数据的操作之前。这个语句真正执行的时候,因为碰到唯一键 c 冲突并没有插入成功,但也也没有将自增值再改回去。

 

事务回滚导致自增主键id不连续:

生成了自增id之后,因为事务回滚,其实并没有插入数据,但是自增主键是不会回滚的。

 

 

MySQL自增主键不能回退是为了提升性能

两个并行执行的事务,在申请自增值的时候,为了避免两个事务申请到相同的自增 id,肯定要加锁,然后顺序申请。InnoDB 放弃了这个设计,语句执行失败也不回退自增 id。只保证了自增 id 是递增的,但不保证是连续的

 

自增 id 锁并不是一个事务锁,而是每次申请完就马上释放,以便允许别的事务再申请。

 

innodb_autoinc_lock_mode,默认值是 1

1)设置为 0 时,即语句执行结束后才释放锁;

2)设置为 1 时:普通 insert 语句,自增锁在申请之后就马上释放;类似 insert … select 批量插入数据的语句,自增锁还是要等语句结束后才被释放;(为了数据的一致性)

3)设置为 2 时,所有的申请自增主键的动作都是申请后就释放锁

 

普通的 insert 语句里面包含多个 value 值的情况下,即使 innodb_autoinc_lock_mode 设置为 1,也不会等语句执行完成才释放锁。因为这类语句在申请自增 id 的时候,是可以精确计算出需要多少个 id 的,然后一次性申请,申请完成后锁就可以释放了。

 

 

针对上面insert select批量插入语句,如果 binlog_format=statement,binlog 会怎么记录呢?假设AB两个 session 是同时执行插入数据命令的,所以 binlog 里面对表 t2 的更新日志只有两种情况:要么先记 session A 的,要么先记 session B 的。这个时候到备库执行的时候session肯定都是连续的,而主库上则不一定是连续的。会导致主备不一致

 

主备不一致的解决方案:

1,innodb_autoinc_lock_mode 设置为1

2,innodb_autoinc_lock_mode 设置为 2,同时 binlog_format 设置为 row,如实记录主库的操作

 

 

主键 id 出现自增 id 不连续的第三种原因

对于批量插入数据的语句,MySQL 有一个批量申请自增 id 的策略

同一个语句去申请自增 id,每次申请到的自增 id 个数都是上一次的两倍。1、2、4、8等等,但是实际用不了这么多批量申请的id

 

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论