一、undo log
redo log 记录了事务的行为,但是事务有时还需要进行 “回滚” 操作,就需要使用 undo log。如果用户执行的事务或语句由于某种原因失败了,又或者用户用一条 ROLLBACK 语句请求回滚,就可以利用这些 undo log 信息将数据回滚到修改之前的样子。
undo log 存放在数据库内部的一个特殊段(segment)中,这个段被称为 undo 段。undo 段位于共享表空间内。undo log 是逻辑日志,因此只是将数据库逻辑地恢复到原来的样子。所有修改都被逻辑的取消了,但是数据结构和页本身在回滚之后可能大不相同。这是因为在多用户并发系统中,可能会有多个并发事务。数据库的主要任务就是协调对数据记录的并发访问。比如,一个事物在修改当前一个页中某几条记录,同时还有别的事务对同一个页中另外几条记录进行修改。因此,不能将一个页回滚到事务开始的样子,因为这样会影响其他事务正在进行的工作。
因此,当 InnoDB 存储引起回滚时,实际上做的是与先前相反的工作。对于 INSERT,会完成一个 DELETE;对于 DELETE,会完成 INSERT;对于 UPDATE 操作,会执行一个相反的 UPDATE,将修改前的行放回去。
undo log 的另一个作用是实现 InnoDB 存储引擎中的 MVCC 功能。当用户读取一行记录时,若该功能已经被其他事务占用,当前事务可以通过 undo log 来完成。当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过 undo log 读取之前的行版本信息,以次实现非锁定读取。
注意:undo log 也会产生 redo log,也就是 undo log 的产生会伴随着 redo log 的产生,这是因为 undo log 也需要持久性的保护。