这里写自定义目录标题
- 一、事务回滚
- [二、mysql InnoDB引擎如何实现回滚操作](#二、mysql InnoDB引擎如何实现回滚操作)
-
- [2.1 InnoDB引擎的 undo log](#2.1 InnoDB引擎的 undo log)
- [2.2 具体实现](#2.2 具体实现)
-
- [2.2.1 insert 操作](#2.2.1 insert 操作)
- [2.2.2 delete 操作](#2.2.2 delete 操作)
- [2.2.3 update 操作](#2.2.3 update 操作)
主要参考资料为:《Mysql 是怎样运行的》
一、事务回滚
根据原子性的定义,一个事务中的操作要么全部成功,要么全部失败。事务回滚机制就是保证"全部失败"的手段。
二、mysql InnoDB引擎如何实现回滚操作
2.1 InnoDB引擎的 undo log
undo log(即撤销日志)是InnoDB引擎中用来记录事务执行过程中所做的修改操作的日志。
当一个事务修改数据库中的数据时,它会生成一些更改操作,这些更改操作就会记录在undo log 中。
下图中为简要描述事务执行时undo log的产生情况,执行第一步后会产生对应的 undo log1,执行第二步后会产生 undo log2。如果此时需要回滚,那么按照 undo log 链表执行一遍即可。
2.2 具体实现
对数据库中的操作而言,无外乎insert、delete、update三中操作,而不同的操作也会生成不同的undo log。
2.2.1 insert 操作
插入操作向数据库中增加了一条记录,回滚时就需要删除掉这条记录,此时 undo log 只需要记录该记录的主键即可。
2.2.2 delete 操作
删除操作会将记录从数据库中删除,在InnnoDB中删除操作氛围两步:
- 逻辑删除阶段:将当前记录的deleted_flag 字段标记为 1
- 事务提交后,会有专门的线程将记录删除掉,此后该记录被真正删除。
从上述步骤可知,回滚操作只会出现在第一阶段。
对于删除操作的 undo log,主要保存了旧记录的各列信息、roll_pointer(指向 undo log的指针)、trx_id(事务id)。
2.2.3 update 操作
update 操作可以拆分为两个操作:删除旧记录,插入新记录。在InnoDB中对应的 undo log 格式如下,该日志中主要存放修改所涉及的列的数量、原有列的数值信息、roll_pointer 指针。
对于 update 所更新的字段不同,同样分为两类,两种类别所产生的 undo log 不同。
-
不涉及了主键字段
由于不涉及主键字段,InnoDB会在删除阶段直接将记录删除,只生成一条 undo log。
-
涉及主键字段
涉及主键字段的更新,将会影响该记录在聚簇索引中的位置。因此,在删除时会使用逻辑删除,然后插入新的记录。这种情况下,会生成两条 undo log。