2021-01-05:mysql的自增id的实现逻辑是什么样子的?
福哥答案2021-01-05:
答案来自这个链接:[ 每日一面 - mysql 的自增 id 的实现逻辑是什么样子的?](https://zhanghaoxin.blog.csdn.net/article/details/112223230)
Key TakeAways
1.InnoDB 引擎中 有三种 AutoIncrement 锁模式:
innodb_autoinc_lock_mode=0(traditional lock mode):获取表锁,语句执行结束后释放。
innodb_autoinc_lock_mode=1(consecutive lock mode,MySQL 8.0 之前默认 ):对于不确定插入数量的语句(例如INSERT ... SELECT, REPLACE ... SELECT和LOAD DATA)和 innodb_autoinc_lock_mode=0 一样,其他的确定数量的语句在执行前先批量获取 id,之后再执行语句。
innodb_autoinc_lock_mode=2(interleaved lock mode,MySQL 8.0+ 默认 ):采用乐观锁, CAS 更新计数器获取。
2.AutoIncrement 计数器在 MySQL 8.0 之前,存储在内存中,在 MySQL 8.0 之后,持久化存储到磁盘。通过每次更新写入 Redo Log,并在检查点刷入 innodb 引擎表中记录下来。
3.AutoIncrement 的 id 可以让新数据聚集在一起,利于大部分 OLTP 业务(访问频率在最近一天,一周,或者几个月内比较活跃,而超过一段时间内的数据很少访问)。如果是这类业务推荐使用自增主键,将业务主键(UUID)作为二级的唯一索引使用。
4.如果考虑分布式性能以及避免 AutoIncrement 带来的锁性能问题,可以考虑使用 ID 生成器生成:全局趋势增长的主键。
为何主键要 Auto Increment 而不是 UUID
ySQL InnoDB 引擎默认主键索引是 B+ 树索引,也是聚集索引,为何叫聚集索引呢?
以 InnoDB 作为存储引擎的表,表中的数据都会有一个主键,即使你不创建主键,系统也会帮你创建一个隐式的主键。这是因为 InnoDB 是把数据存放在 B+ 树中的,而 B+ 树的键值就是主键,在 B+ 树的叶子节点中,存储了表中所有的数据。这种以主键作为 B+ 树索引的键值而构建的 B+ 树索引,我们称之为聚集索引。
存储中,聚集索引的数据,会根据索引的值,对应的数据也会聚集存储在一起。
AutoIncrement 原理
我们这里只关心 InnoDB 引擎的。
AutoIncrement 最大值
AutoIncrement 最大值,和列类型相关。最大可以设置列类型为 UNSIGNED BIGINT,这样最大值就是 18446744073709551615。 超过这个值继续生成则还是 18446744073709551615。不会再增加。
AutoIncrement 锁模式
获取 AutoIncrement 最新值,需要涉及到锁。目前有三种锁模式,对应 innodb_autoinc_lock_mode 的值, 0 ,1,2. MySQL 8.0 之后,默认为 2, 在这之前,默认为 1
1.innodb_autoinc_lock_mode=0(traditional lock mode)
传统的auto_increment机制,这种模式下所有针对auto_increment列的插入操作都会加表级别的AUTO-INC锁,在语句执行结束则会释放,分配的值也是一个个分配,是连续的,正常情况下也不会有间隙(当然如果事务rollback了这个auto_increment值就会浪费掉,从而造成间隙)。
2.innodb_autoinc_lock_mode=1(consecutive lock mode)
这种情况下,针对未知数量批量插入(例如INSERT ... SELECT, REPLACE ... SELECT和LOAD DATA)才会采用AUTO-INC锁这种方式,而针对已知数量的普通插入,则采用了一种新的轻量级的互斥锁来分配auto_increment列的值。这种锁,只会持续到获取一定数量的 id,不会等待语句执行结束在释放。也就是拿轻量级锁提前分配好所需数量的 id 之后释放锁,再执行语句。当然,如果其他事务已经持有了AUTO-INC锁,则simple inserts需要等待。当然,这种情况下,可能产生的间隙更多。
3.innodb_autoinc_lock_mode=2(interleaved lock mode)
这种模式下任何类型的inserts都不会采用AUTO-INC锁,性能最好,但是在同一条语句内部产生auto_increment值间隙。其实这个就是所有语句对于同一个值进行 Compare-And-Set 更新,类似于乐观锁。这个锁模式对statement-based replication的主从同步都有一定问题。因为同步传输的是语句,而不是行值,语句执行后的差异导致主从可能主键不一致。
AutoIncrement 存储
AutoIncrement 计数器在 MySQL 8.0 之前,存储在内存中,每次启动时通过以下语句初始化:
SELECT MAX(ai_col) FROM table_name FOR UPDATE;
在 MySQL 8.0 之后,持久化存储到磁盘。通过每次更新写入 Redo Log,并在检查点刷入 innodb 引擎表中记录下来。
所以,在MySQL 8.0 之前,如果 rollback 导致某些值没有使用,重启后,这些值还是会使用。但是在 MySQL 8.0 之后就不会了。
***
[每日一面 - mysql 的自增 id 的实现逻辑是什么样子的?](https://zhanghaoxin.blog.csdn.net/article/details/112223230)
[2021-01-05:mysql的自增id的实现逻辑是什么样子的?](http://bbs.xiangxueketang.cn/question/1007)
[评论](https://user.qzone.qq.com/3182319461/blog/1609801219)
2021-01-05:mysql的自增id的实现逻辑是什么样子的?的更多相关文章
- mysql 数据库自增id 的总结
有一个表StuInfo,里面只有两列 StuID,StuName其中StuID是int型,主键,自增列.现在我要插入数据,让他自动的向上增长,insert into StuInfo(StuID,Stu ...
- MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)
测试缘由 一个开发同事做了一个框架,里面主键是uuid,我跟他建议说mysql不要用uuid用自增主键,自增主键效率高,他说不一定高,我说innodb的索引特性导致了自增id做主键是效率最好的,为了拿 ...
- MYSQL获取自增ID的四种方法
MYSQL获取自增ID的四种方法 1. select max(id) from tablename 2.SELECT LAST_INSERT_ID() 函数 LAST_INSERT_ID 是与tabl ...
- mysql数据库自增id重新从1排序的两种方法
mysql默认自增ID是从1开始了,但当我们如果有插入表或使用delete删除id之后ID就会不会从1开始了哦. 使用mysql时,通常表中会有一个自增的id字段,但当我们想将表中的数据清空重新添 ...
- DBS-MySQL:MYSQL获取自增ID的四种方法
ylbtech-DBS-MySQL:MYSQL获取自增ID的四种方法 1.返回顶部 1. 1. select max(id) from tablename 2.SELECT LAST_INSERT_I ...
- mysql数据库表自增ID批量清零 AUTO_INCREMENT = 0
mysql数据库表自增ID批量清零 AUTO_INCREMENT = 0 #将数据库表自增ID批量清零 SELECT CONCAT( 'ALTER TABLE ', TABLE_NAME, ' AUT ...
- mysql 返回自增id
String dateNow= DateTime.Now.ToString("yyyyMMddhhmmss"+ new Random().Next(1, 99)); //随机数 ...
- MySQL中自增ID起始值修改方法
在实际测试工作过程中,有时因为生产环境已有历史数据原因,需要测试环境数据id从某个值开始递增,此时,我们需要修改数据库中自增ID起始值,下面以MySQL为例: 表名:users; 建表时添加: ); ...
- MySQL 的自增 ID 用完了,怎么办?
一.简述 在 MySQL 中用很多类型的自增 ID,每个自增 ID 都设置了初始值.一般情况下初始值都是从 0 开始,然后按照一定的步长增加.在 MySQL 中只要定义了这个数的字节长度,那么就会 ...
- MySQL 使用自增ID主键和UUID 作为主键的优劣比較具体过程(从百万到千万表记录測试)
主键类型 SQL语句 运行时间 (秒) (1)模糊范围查询1000条数据,自增ID性能要好于UUID 自增ID SELECT SQL_NO_CACHE t.* FROM test.`UC_US ...
随机推荐
- windows tips
u启动经典dos工具实现硬盘分区教程 https://jingyan.baidu.com/article/a3f121e4dbe55afc9052bbfe.html?st=2&net_type ...
- python中的反射机制
转自https://www.cnblogs.com/renjie1105/p/15909285.html python反射简介 在做程序开发中,我们常常会遇到这样的需求:需要执行对象里的某个方法,或需 ...
- 狂神说SpringBoot笔记之编写一个http接口
编写一个http接口 1.1.在主程序的同级目录下,新建一个controller包,一定要在同级目录下,否则识别不到 2.代码 1 package com.example.app01.demo.api ...
- SqlServer 高并发的情况下,如何利用锁保证数据的稳定性
sql的锁机制,是时刻贯彻在每一次的sql事务中的,为了理解更透彻,介绍锁之前,我们得先了解,锁是为了干什么!! 1.数据库异常情况 1.1 先来聊聊数据可能发生个异常状况 1)脏读:读未提交,顾名思 ...
- Yolov5——训练目标检测模型
项目的克隆 打开yolov5官网(GitHub - ultralytics/yolov5 at v5.0),下载yolov5的项目: 环境的安装(免额外安装CUDA和cudnn) 打开anaconda ...
- ABAP 调用HTTP上传附件(二)之中文乱码
1.这篇文章的由来 之前已经发表了<ABAP 调用HTTP上传附件>的文章,详细介绍了如何通过HTTP请求传输附件,可点击链接参考原有文档 因为之前对传输文件的中文文件名处理上解释不够详细 ...
- Vue+ElementUI动态显示el-table某列(值和颜色)的方法
方法一:结合 template scope组件和 v-if 语法判断 例1:值 <el-table-column prop="status" label="车辆状态 ...
- IO流中「线程」模型总结
目录 一.基础简介 二.同步阻塞 1.模型图解 2.参考案例 三.同步非阻塞 1.模型图解 2.参考案例 四.异步非阻塞 1.模型图解 2.参考案例 五.Reactor模型 1.模型图解 1.1 Re ...
- python入门教程之三编码问题
1编码问题 Python文件中如果未指定编码,在执行过程中会出现报错: !/usr/bin/python print ("你好,世界") 以上程序执行输出结果为: 文件" ...
- [Linux]调整swap
在启动Tomcat的过程中,tomcat/catalina.out中报出如下故障: > /opt/govern/wydaas/logs/catalina.out # There is insuf ...