标签:
第一次了解mysql的时候,看到了undo log这个名词,却不知道undo log是干什么,为了能够继续看明白一些mysql的资料,不得不先弄明白undo log是什么? undo log的原理是什么?它与数据库的其它特性如何配何。
这篇笔记只从原理上分析,不涉及具体的实现方法。
undo log是一种日志,日志中记录对于数据库的反向操作。
如果把数据库的内容当做一种状态机,那么数据的写操作就是修改状态机的命令,而undo 就对应修改状态机的反向命令。
所以理论上每一个对于状态机修改的命令都会产生对应一条相当的undo log,以便事务回滚的时候,能够把状态机修改到事务原来的样子。
假如我们有一个事务:
create table table1(c1 int);
begin transaction;
insert into table1 (100); //数据库执行这一条命令的时候应该产生一条undo日志,能够把这语句对于状态机的修改回复到原来没有修改的状态 , undo 应该是 delete table1 where c1 = 100;
insert into table1(200); // undo 应该是 delete table1 where c1 = 200;
update table1 set c1 = 300 where c1 = 200; // undo: update table1 set c1 = 200 where c1 = 300
rollback;
其实这个问题问的不好,因为undo是设计出来,没有什么直接的因素说非得有undo log, 自己比较熟习的postgres就没有undo log。下面就与postgres进行比较,来看mysql为什么有undo
mysql与postgres都是基于mvcc的,但是mysql与postgres对于mvcc的实现不太一样。
为什么要有mvcc? 因为mvcc与它的前辈lock based相比,能够实现读写不冲突这一个特性,如果没有mvcc,一个事务读一条数据,另外一个事务写同一条数据,这两个事务是无法并发执行的,后一个事务必须要等前一个事务执行完成之后才能执行,但是有了mvcc,这两个事务就可以并发执行,这及大的提高的数据库的性能,以至于现在主流的数据库都实现了mvcc。
但是各个数据对于mvcc的实现略有不同:
其中mysql的实现就有undo log,而postgres的实现里面没有undo log.但是postgres里面有clog, clog记录了每一事务的状态。
postgres的每一行的所有的版本是存放一起的,它允许保留aborted事务产生的版本, mysql的最新版本保存在表空间,而历史版本则保存在undo log里面。mysql在事务回滚的时候,应该是同步利用undo log把最新版本的恢复成修改之前的状态,同时删除对应事务产生的undo log,而postgres则是通过异步的vaccum,来把aborted事务产生的历史版本给删除。
mvcc里面最重要的一点就是行可见性判断。这里简单的描述一下postgres的行可见性判断与mysql的行可见性判断。
上面已经提到,undo这个动作发生成rollback一个事务的时候。
同时也发生在数据recovery的时候,因为有些事务正在执行过程中,数据crash了,那么数据库重启做完redo后,要把对应没有提交的事务的动作undo一下。
同时undo log记录历史版本,读历史版本的时候,也要从undo log里面去读。
以上关于mysql的都是自己从互联网上看资料得来的,理解的并不一定正确,后面会根据mysql代码来验证一下。
标签:
原文地址:http://www.cnblogs.com/alkfbb/p/5014820.html