InnoDB存储引擎中,另一个日志是undo日志。
它用来帮助事务回滚以及MVCC的功能。
用户通过一条roolback语句请求回滚,这是就可以利用undo信息将数据回滚到修改之前的样子。
与redo不同,undo存放在数据库内部的一个特殊段(segment)中,称为undo(segment)。undo段位于共享表空间内。
undo是逻辑日志。回滚之后,所有修改都被逻辑地取消了,但是数据结构和页本身在回滚之后可能不相同。
当InnoDB存储引擎回滚时,它实际做的事与先前相反的工作。对于Insert,InnoDB存储引擎会完成一个delete;对于delete,InnoDB会完成一个Insert;对于update,InnoDB存储引擎会执行一个相反的update。
MVCC的实现,是通过undo来完成。当读取一行记录时,已经被其他事务占用,当前事务可以通过undo读取之前的行版本信息,实现非锁定读取。
注意undo log会产生redo log,因为undo log也需要持久性的保护。
对于undo的管理,InnoDB存储引擎同样采用段的管理方式。Innodb存储引擎有rollback segment,每个回滚段记录1024个undo log segment,而在每个undo log segment段中进行undo页的申请。共享表空间偏移量为5的页(0,5)记录了所有rollback segment header所在的页,这个页的类型为FIL_PAGE_TYPE_SYS。
在InnoDB V1.1版本之前,只支持一个rolback segment,所以同时在线的事务限制为1024。从V1.1版本开始支持最大128个rollback segment,同时在线的事务限制提高到了128*1024个。
下面这三个餐素可以对rollback segment进行设置:
innodb_undo_directory:用于设置rollback segment文件所在的路径。即可以设置为独立表空间。默认值“.”,当前InnoDB存储引擎的目录。
innodb_undo_logs:用来设置roolback segment个数,默认值128。
inodb_undo_tablespaces:用来设置构成rollback segment文件的数量,这样rollback segment可以较为平均的分布在多个文件中。文件前缀为undo。
当事务提交时,InnoDB存储引擎会做以下动作:
1.将undo log放入列表中,供之后的purege操作。
2.判断undo log所在页是否可以重用,若可以分配给下一个事务使用。
事务提交后并不能马上删除undo及undo log所在的页。因为需要支持MVCC,为其他事务此时获取行记录之前的版本。事务提交时将undo log放入一个链表中,由purge线程来判断是否可以删除。
InnoDB存储引擎可以对undo页进行重用。首先undo log放入链表中,然后判断undo页的使用空间是否 小于3/4,如果是那么该undo页可以重用,之后新的undo log记录卸载当前undo log记录后面。
undo log分为insert undo log和update undo log两种。
insert undo log是在insert操作中产生的undo log,只对事务本身可见,其他事务部可见(隔离性)。所以在事务提交后,就没用了,可以直接删除。
update undo log是在delete和update操作中产生的undo log。因为支持MVCC机制的关系,不能直接删除。提交时房屋undo log链表中,等待purge线程进行最后的删除。