事务回滚机制
其实,讨论MySQL的事务回滚机制,也就是在说MySQL的事务原子性是如何实现的(关于事务之前文章中有过简单介绍)。
所谓原子性,就是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做;如果事务中的一个sql语句执行失败,则已执行的语句必须回滚,数据库会退回到事务前的状态。
我们可以这么理解,就是说如果事务失败了,那么它对我们的数据库是没有任何影响的。
实现原理
在说明原理之前,需要首先介绍一下MySQL的事务日志。
MySQL的日志有很多种,如二进制日志、错误日志、查询日志、慢查询日志等,此外InnDB引擎还提供了两种事务日志:redo log(重做日志)和undo log(回滚日志)。
- 其中redo log用于保证事务持久性;
- undo log则是事务原子性和隔离性实现的基础。
我们这里,之所以能够保证原子性,则是靠undo log。
当事务对数据库进行修改时,InnDB会生成对应的undo log;如果事务失败或者调用了rollback,导致事务回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。
undo log属于逻辑日志,它记录的是sql执行相关的信息。当发生回滚时,InnoDB会根据undo log的内容做与之前相反的工作:对于每个insert,回滚时会执行delete;对于每个delete,回滚时会执行insert;对于每个update,回滚时会执行一个相反的update,把数据改回去。
以update操作为例:当事务执行update时,其生成的undo log中会包含被修改行的主键(以便知道修改了哪些行)、修改了哪些列、这些列在修改前后的值等信息,回滚时便可以使用这些信息将数据还原到update之前的状态。
上面这张图,就比较清晰的表示事务回滚的原理,可以看到,每一步数据的更改都伴随着回滚日志的产生。
所以说我们可以得出以下结论:
- 每条数据变更操作都伴随着一条undo log的生成,并且回滚日志必须先于数据持久化到磁盘上。
- 所谓回滚也就是根据回滚日志做逆向操作。 回滚过程如下:
参考:https://blog.csdn.net/m0_49449205/article/details/114988580