0%

MySQL笔记[InnoDB]事务-undo log

一、undo的概念
事务在进行回滚时,就需要undo日志。因此,在对数据库进行修改时,innodb引擎不仅产生redo log,还会产生 一定量的undo log。
redo log存储在重做日志文件中,而undo log则是存在数据库内部的一个特殊段(segment)中。这个段称为undo 段(undo segment),undo段位于共享表空间里面。可以通过py_innnodb_info.py工具来查看共享表空间ibdata1中undo的数量。

Total number of page: 4864:
Insert Buffer Bitmap: 1
System Page: 135
Transaction system Page: 2
Freshly Allocated Page: 3661
Undo Log Page: 937
File Segment inode: 6
B-tree Node: 119
File Space Header: 3

可以看到undo的数量为937个。undo是逻辑日志,它只是逻辑上恢复数据库,并不是物理上把数据库恢复到原来的样子。除了回滚,undo日志还有个作用是MVCC。当用户读取一条记录时,若已经被其它事务占用,则当前事务可以通过undo读取之前的行版本信息,实现非锁定读。

二、undo存储管理
innodb引擎对undo的管理采用段的方式,引擎的每个回滚段(rollback segment)记录了1024个undo log segment,而在每个undo log segment中进行页的申请。共享表空间偏移量为5(0,5)的页记录了所有rollback segment header所在的页,这个页的类型为FIL_PAGE_TYPE_SYS。
1.2版本后,可以通过参数对rollback segment进行控制:
• Innodb_undo_directory 设置rollback segment文件所有的路径
• Innodb_undo_logs 设置rollback segment的个数
• Innodb_undo_tablespace 设置构成rollback segment文件的数量
Undo log segment分配页并写入undo log这个过程也需要写入重做日志,当事务提交时,innodb引擎会:
将undo log放到列表中,等待后面的purge操作;判断undo log所在的页是否可以重用,若可以,分配给下个事务使用。事务提交后不能马上删除undo log和undo log所在的页,因为有可能其它事务需要通过undo log来得到行记录之前的版本。什么时候删除undo log和undo log所在的页,由purge线程来确定。

三、undo log的格式
undo log分为insert undo log和update undo log两种格式,insert操作产生insert undo log,因为insert操作只对本事务可见,别的事务不可见,因此执行后可以删除undo 日志,不需要purge操作。
Insert undo log的格式如下图:

innodb77

*代表为存储的字段进行了压缩,next两个字节,代表下一个undo log的位置,尾部的start两个字节记录的是undo log的开始位置。Type_cmpl一个字节,代表的是undo log的类型。对于insert undo log,它的值总是1。
Undo_no记录的是事务的ID,table_id记录的是undo log所对应的表对象,这两个都是压缩后保存的,接着的部分记录了所有的主键列和值,rollback时,根据这些记录的值,可以定位到具体的记录,删除掉即可。

Update undo log记录的是update和delete操作的undo log。该undo log可能需要提供MVCC机制,因此不能在事务提交时就删除,提交时放入undo log链表,等待purge线程删除。Update undo log的格式如下图:

innodb78

字段next、 start、undo_no、table_id的含义和insert undo log是一样的,对于type_cmpl,由于update undo log还有分类,可能为以下的值:
• 12 TRX_UNDO_UPD_EXIST 更新non-delete-mark的记录
• 13 TRX_UNDO_UPD_DEL_REC 将delete的记录标记为not delete
• 14 TRX_UNDO_DEL_MARK_REC 将记录标记为delete
Update vector表示update操作导致发生改变的列,每个修改的列信息都记录在undo log中。对于不同的undo log类型,可能还会记录对索引所做的修改。


参考《MySQL技术内幕 -InnoDB存储引擎》整理,如侵权请联系vinin@163.com