Undo log日志回放

引言:一个看起来正确的过程

系统宕机后需要重启,重启过程中需要对事务涉及到的数据进行“整理”,包括:

1. 宕机时刻尚未提交的事务对数据的修改需要回滚


实现整理的过程称之为“日志回放”。通过从后向前回放Undo Log日志,直到找到commit点为止,这样就保证了数据一致性。


上面的过程看起来很完美。真的完美吗?问题出在这里:如果系统中同时有多个事务在执行,Undo Log中的commit点该如何定义呢?可能存在多个等待Commit的点。

(继续之前考虑一下Global Serializability,多个commit点与此冲突吗?)



实战:可以工作的过程

方法1:系统重启回放日志,只需要从后往前扫描日志文件,对于所有没有commit的事务按照日志记录中的数据做回滚操作。

这个方法肯定是可以工作的,其问题在于要求扫描所有commit日志,代价不菲。


方法2:使用Checkpoint,拉起一个大栅栏。

Checkpoint可以看做是对引言中“commit点“的展开,它好比一个较宽的栅栏(fence),将所有已经开始、尚未commit的事务都记录下来,等待这些事务完成之后再在日志中写入一条“在这个栅栏架起来之前的那些状态一致了”的标记。 为什么是“架起来之前的”呢?因为在架起栅栏后有一段等待事务完成时间,这段时间里会有新的事务发起,他们也会继续写日志,对于这些事务Checkpoint不关注。


生成checkpoint的过程:

1. 在日志中写下CREATE_CKPT(T1,T2,..,Tn),其中Ti表示写入CREATE_CKPT之前尚未完成的事务

2. 等待T1~Tn这些事务完成。在等待过程中可能会有新的事务写日志。

3. 在日志中写入END_CKPT


日志回放过程:

1. 从后往前扫描日志,如果先遇到END_CKPT,那么说明CREATE_CKPT中记录的T1~Tn这些事务都已经完成,将日志回放至CREATE_CKPT处即可。之前的日志均可以丢弃。如果先遇到CREATE_CKPT,那么说明T1~Tn这些事务可能还有没完成的,那么为了保证Global Serialization,将日志回滚到T1~Tn中最早出现的那一条之前即可。例如T3是T1~Tn中最先开始的事务,则将事务回滚检查做到T3之前即可,因为T3前的所有数据均已经确保Commit了。


剩余问题:

如何保证事务的Global Serializability?



参考文献:无施的http://nosql-wiki.org/foswiki/bin/view/Main/TransactonLog


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值