InnoDB Undo Log
- 简介
Undo Log包含了一系列在一个单独的事务中会产生的所有Undo Log记录。每一个Undo Log记录包含了如何undo事务对某一行修改的必要信息。InnoDB使用Undo Log来进行事务的回滚和MVCC机制。在逻辑存储上,Undo Log位于Undo Log 段中,后者位于回滚段(roll back segments)中。在目前的最新版本中,会馆段不仅仅可以位于系统表空间(例如data目录下面的ibdata1文件就是一个系统表空间)、临时表空间,也可以通过配置放置到undo 表空间中。InnoDB支持128个回滚段,其中32个用于临时表的事务。剩下的96个,每一个支持1023个并发数据修改事务。
2. Undo Log物理结构
Undo Log的物理结构可以直接参照博文 :
http://insidemysql.blog.163.com/blog/static/2028340422013325115250722/
http://insidemysql.blog.163.com/blog/static/202834042201341011347494/
其中有两个疑惑点:
一是第二篇博文中 UPDATE t SET c=2 WHERE a=1; 语句的说明中,写道:列的值(a=1),我认为是作者的笔误,应该是 c=1;
二是 80 00 01这是表示值为1,这里应该是InnoDB特殊处理了(猜测,可能是1开始表示为正数),作者说80 00 01表示为1是因为计算机中存储的是有符号整数,但是1的有符号int表示形式应该是 00 00 01。
3.Undo Log逻辑内容
光看Undo Log的物理结构可能有点不好理解,这里讲解一下自己的理解。考虑下面这样的一些SQL。
CREATE TABLE my_tb(
id int auto_increment,
name varchar(255) not null,
sex varchar(255) not null,
primary key(id),
key(name)
)
#事务一开始 插入一条数据 假设id=1 提交
BEGIN;
INSERT INTO my_tb(name,sex) values('a','boy');
COMMIT;
#事务二开始 删除操作 不提交
BEGIN;
DELETE FROM my_tb WHERE id=1;
#回滚不提交
ROLLBACK;
#事务三开始 更新操作
BEGIN;
UPDATE my_tb set name='b' where id=1;
事务一在提交之前,会有一条这样子的Undo Log:
插入了一条id=1的记录 。
是的,插入语句中的undo log只会记录 unique key(应该包括主键和所有的唯一键,猜测未证实,主键肯定是有的),而不包括其他字段的信息。
事务二提交之前,会有一条这样子的Undo Log:
删除了一条id=1的记录,他的name为a,他的sex为boy。
这时候不仅仅会记录主键,也会记录所有字段的值。
事务三提交之前,会有一条这样子的Undo Log:
更新了一条id=1的记录,他的name为a。
注意这时候记录的name不是b,而是a。
为什么Undo Log翻译过来是这样子的?其实思考一下Undo Log是用来做什么的就知道了。Undo Log被用于回滚和MVCC,两者都需要恢复或者获取到之前版本的信息。
如果你插入了一条数据,通过插入数据的Undo Log中唯一索引字段和值查找到对应的记录,然后进行删除(回滚时)或者忽略(MVCC);
如果你更新了了一条数据,找到对应的记录之后,通过记录的原始值(name='a')恢复成原来的记录;
如果你删除了一条数据,那么就需要完整的记录信息,才能进行回滚和恢复。
当然,Undo Log中记录的信息不像我说的这么简单,具体的信息还是查看上面的两篇博文,从物理结构中理解Undo Log。另外,Undo Log中提供的信息其实不是完整的,如果你的系统故障,导致已经提交的事务涉及的记录没有刷新到磁盘而丢失更新,这时候就需要redo log和 double write buffer一起配合进行恢复了。