自增ID未回滚

首先做一个测试

CREATE TABLE auto_inc_test( id int auto_increment, test_id int, primary key id(id))ENGINE=InnoDB;mysql> start transaction;
mysql> INSERT INTO auto_inc_test (test_id) values (1);
mysql> INSERT INTO auto_inc_test (test_id) values (2);
mysql> INSERT INTO auto_inc_test (test_id) values (3);
mysql> rollback;mysql> INSERT INTO auto_inc_test (test_id) values (1);
mysql> SELECT * FROM auto_inc_test;
+----+---------+
| id | test_id |
+----+---------+
|  3 |       1 |
+----+---------+
1 row in set (0.01 sec)

可以看到rollback之后新增一行数据,id列并没有跟随test_id列一起回滚清空,而是继续从3开始增长。

这是数据库有意设置成不跟随回滚的,因为没有办法解决多个事务commit/rollback时自增id变化的问题。

举例一种情况:

业务1开启事务
业务1插入一条数据,得到一个id(自增列),假设为666
业务2开启事务,插入一条数据,得到一个id,为667
业务2 commit
业务2打印出这条数据
业务1回滚

这时如果自增ID跟着回滚,但是业务2已经使用上了id 667,所以如果说要让id回滚,业务2的数据也要回滚,这个矛盾是不能解决的,因此设计成自增列不会跟着回滚。

Auto Increment的实现

InnoDB的自增(Auto Increment)是通过一个自增计数器(AUTO_INCREMENT counters)来实现的。
这个计数器的计数存储分两种:
1、MySQL5.7及更早的版本中,计数存储在内存(Main Memory)中,也就是说,每次关机、重启都会导致计数器的计数丢失。因此,当重启系统/清空内存等操作之后,在下一次插入数据的时候,会首先执行如下语句以将正确的计数值赋予自增计数器:

SELECT MAX(auto_increment_field) FROM table_name FOR UPDATE;

2、在最新的MySQL8中,每一次新增数据行,或者说每次自增计数器的变动,当前最新的自增计数器数值都会被写入到redo log中,同时还会在每次checkpoints保存至engine-private system table。这让计数器的数值不会因为重启而丢失,因为redo log是一种disk-based的存储,用于在系统crash时恢复数据用的。

延伸阅读
redo log :The redo log is a disk-based data structure used during crash recovery to correct data written by incomplete transactions. (https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.html)
checkpoint:As changes are made to data pages that are cached in the buffer pool, those changes are written to the data files sometime later, a process known as flushing. The checkpoint is a record of the latest changes (represented by an LSN value) that have been successfully written to the data files.(https://dev.mysql.com/doc/refman/8.0/en/innodb-checkpoints.html)

存储之后轮到crash后自增列的恢复,系统会先获取表中最大的自增列数值,记为v1,同时又获取上一次checkpoints后redo log记录的计数器值,记为v2,最终生效的为v1、v2中更大的值作为当前的counter值。v1大于v2的情况应该是crash前未来得及写入到redo log的情况。

更多InnoBD实现Auto Increment的内容参考:https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html

MySQL事务 - 自增ID的回滚以及Auto Increment在InnoDB的实现相关推荐

  1. mysql事务未提交 也未回滚

    文章目录 一.场景模拟 二.紧急处理 三.原因分析 四.相关命令 1.查看正在执行的事务 2.查看正在锁的事务 3.查看等待锁的事务 4.查看所有的线程列表 5.定位未提交的事务执行的sql语句 公司 ...

  2. MySQL 中的重做日志,回滚日志以及二进制日志的简单总结

    转载自 MySQL 中的重做日志,回滚日志以及二进制日志的简单总结 MySQL中有六种日志文件,分别是:重做日志(redo log).回滚日志(undo log).二进制日志(binlog).错误日志 ...

  3. 线上 MySQL 的自增 id 用尽怎么办?被面试官干趴下了!

    点击下方"Java编程鸭"关注并标星 更多精彩 第一时间直达 MySQL的自增id都定义了初始值,然后不断加步长.虽然自然数没有上限,但定义了表示这个数的字节长度,计算机存储就有上 ...

  4. MySQL 使用自增ID主键和UUID 作为主键的优劣比較具体过程(从百万到千万表记录測试)...

    測试缘由 一个开发同事做了一个框架.里面主键是uuid.我跟他建议说mysql不要用uuid用自增主键,自增主键效率高,他说不一定高,我说innodb的索引特性导致了自增id做主键是效率最好的,为了拿 ...

  5. MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)...

    Reference: https://blog.csdn.net/mchdba/article/details/52336203 一个开发同事做了一个框架,里面主键是uuid,我跟他建议说mysql不 ...

  6. 0046 @Transactional注解的几个参数--事务传播控制--事务隔离级别--异常与回滚

    0046 @Transactional注解的几个参数--事务传播控制--事务隔离级别--异常与回滚 参考文章: (1)0046 @Transactional注解的几个参数--事务传播控制--事务隔离级 ...

  7. java事务什么时候回滚_spring事务什么时候会自动回滚

    在java中异常的基类为Throwable,他有两个子类xception与Errors.同时RuntimeException就是Exception的子类,只有RuntimeException才会进行回 ...

  8. MySQL数据库的事务开启,提交和回滚

    事务(transaction)是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位. 基于事务的原子性.一致性.隔离性和持续性特征,可以将相关的数据操作定义到一个事务 ...

  9. 面试官问:如果MySQL的自增 ID 用完了,怎么办?

    欢迎关注方志朋的博客,回复"666"获面试宝典 如果你用过或了解过MySQL,那你一定知道自增主键了.每个自增id都是定义了初始值,然后按照指定步长增长(默认步长是1).虽然,自然 ...

最新文章

  1. CAD图纸文件中标注的尺寸如何进行隐藏?
  2. 【机器学习基础】深入讨论机器学习 8 大回归模型的基本原理以及差异!
  3. SAP Spartacus 和 SmartEdit 协同工作需要遵循的协议
  4. protobuf java基础
  5. ADO.NET Entity Framework学习笔记(2)建模[转]
  6. c语言中规定的标准文件,标准C语言
  7. hc sr04流程图_HC-SR04超声模块示例代码/原理图/说明书等全套资料
  8. java中实体类中实现Serializable接口的作用
  9. 停用zabbix 自动发现的一些规则
  10. 【图像聚类】基于matlab GUI K-means算法图像聚类【含Matlab源码 1787期】
  11. linux rs232驱动程序,Ubuntu安装USB to RS232驱动
  12. RTKLIB学习:数据下载和数据转换
  13. 用计算机考试的时候怎么用有道词典,(图文教程)有道词典单词书
  14. android qq 目录,手机qq存储路径在哪可以找到
  15. Win10如何删除输入法(删除默认输入法)
  16. agent常见处理问题的处理
  17. 使用JPBC实现双线性对加密算法(BasicIdent体制的java实现)
  18. 跨境企业招聘信息怎么写才能吸引求职者?
  19. 为什么说SQL语句中使用IN性能不高?
  20. springboot服务器没响应,记一次springboot 故障:接口无响应--》CPU 100%---》log无法写入---》磁盘满了...

热门文章

  1. java压缩mp4大小_压缩的mp4视频播放时间太长(exoplayer)
  2. 魔力拍证件照制作小程序
  3. 【输入法】不显示中文
  4. python人脸识别解锁电脑_python人脸识别
  5. POI锁定单元格的问题
  6. 机器学习、深度学习、神经网络学习资料集合(开发必备)
  7. 2012_WOW_Designing Steganographic Distortion Using Directional Filters
  8. 24Python读取PPT文档内容
  9. java转义字符响铃_转义字符
  10. OpenSSL环境搭建(WIN10+VS2017)