该系列主要是我在学习MySQL日志系统的知识总结,主要是总结MySQL日志系统中undo log日志的一些知识点总结。
本篇对undo log日志的一个大致的认识,有一个全局的理解。
一、为什么需要undo log
MySQL事务中,事务是需要保证原子性的,原子性即事务中的操作要么全部完成,要么什么都不做。
一个事务在执行过程中,在事务还未提交之前,如果MySQL发生了崩溃,那要如何回滚事务之前的数据呢?
针对这个问题,我们可以考虑在事务执行的过程中,同时记录回滚数据时需要的信息到一个日志中,那么在事务执行的过程中如果MySQL发生崩溃,那么就可以通过这个日志回滚到事务执行之前的数据。
上述这种日志就是undo log
日志,即回滚日志,undo log
日志保证了事务的ACID特性中的原子性。
二、undo log记录的内容
每当InnoDB引擎对一条记录进行操作(修改、增加、删除)时,要把回滚时需要的信息都记录到 undo log
里,比如:
- 在插入一条记录时,至少要把这条记录中的主键值记录下来,回滚时只需要把这个主键值对应的记录删掉就可以了。
- 在删除一条记录时,至少要把这条记录中的内容记录下来,回滚时再把由这些内容组成的记录插入到表中即可。
- 在修改一条记录时,至少要把被更新的列的旧值记下来,这样之后回滚时再把这些列更新为旧值即可。
例如:
当事务中执行如下语句时:
update user set name = "小明" where id = 10; # 修改之前name = 小红
此时undo log
会记录下该记录的内容,在进行事务回滚时,会执行如下的语句:
update user set name = "小红" where id = 1;
三、与undo log有关的字段
当对一条记录进行更新操作时产生的undo log
日志中,记录会包含两个隐藏列:
- trx_id:记录修改当前记录的事物id,通过该字段可以知道该记录是由哪个事务修改的;
- roll_pointer:roll_pointer指针通过指向
undo log
,从而形成一个引用链,通过该引用链可以找到旧记录;
四、undo log的作用
- 第一个作用:实现事务回滚,保障事务的原子性。事务处理过程中,如果出现了错误或者用户执 行了 ROLLBACK 语句,MySQL 可以利用
undo log
中的历史数据将数据恢复到事务开始之前的状态。 - 第二个作用:实现 MVCC(多版本并发控制)关键因素之一。MVCC 是通过
ReadView + undo log
实现的。undo log
为每条记录保存多份历史数据,MySQL 在执行快照读的时候,会根据事务的 Read View 里的信息,顺着undo log
的版本链找到满足其可见性的记录。