三者定义
- 后像后写要求日志在保存完毕(包括 COMMIT)后,事务才开始写入磁盘。日志记录的是新值。
- 后像前写要求完成数据写入磁盘后再保存日志(写 COMMIT,但之前的记录还是在写磁盘之前写入日志的)。日志记录的是旧值。
- 后像前后写对于保存日志和数据写入磁盘的顺序没有要求(同样, COMMIT 之前的记录还是在写磁盘之前写入日志的)。新旧值日志都要记录。
三者的区别就是写 COMMIT 的时机和记录新值或旧值。
恢复操作
后像后写
后像后写在恢复时,需要从后向前扫描日志找 COMMIT 行,有 COMMIT 的事务需要加入 Redo-list。
然后从前向后扫描日志,如果此事务是 Redo-list 中的,就要重新向 DB 写入数据(不在乎 DB 上的数据是对是错,都要重写)。
后像前写
后像前写在恢复时,需要从后向前扫描日志找 COMMIT 行,有 COMMIT 的事务需要加入 Undo-list。
然后从后向前扫描日志,如果此事务是 Undo-list 中的,就不管它。若不在,就要将 DB 中对应的记录恢复到旧值。
注意,在这里 Undo 不是撤销的意思,是不处理的意思。
后像前后写
后像前后写在恢复时,需要从后向前扫描日志找 COMMIT 行,有 COMMIT 的事务需要加入 Redo-list,无则进入 Undo-list。
然后再从前向后扫描日志,若事务在 Redo-list 中,则重新写其新值。
第三步,从后向前扫描日志,若事务在 Undo-list 中,则恢复到旧值。
注意这里的 Undo-list 中的事务不能不处理了,所以 Undo 又接近于撤销的意思。
区别
后像后写的恢复是找到有 COMMIT 行的事务,要求其重新写过。因为写 COMMIT 是在写磁盘之前,那么没有 COMMIT 的事务肯定是不会写入磁盘的,有 COMMIT 的事务不能确定。
后像前写的恢复是找到没有 COMMIT 行的事务,要求其恢复到旧值。因为写 COMMIT 是在写磁盘之后,那么有 COMMIT 的事务肯定已写入磁盘,没有 COMMIT 的事务不能确定。
后像前后写因为不规定写 COMMIT 的时机,不能作任何保证,只能将两种恢复(写新值和写旧值)都进行一遍!
还需要注意的是几种扫描的方向。在建立 Redo-list 和 Undo-list 时,都是从后向前扫描日志。而写新值要从前向后,写旧值要从后向前。