neuqdarcy

导航

Redo Log 与 Undo Log

本文目的是简单讲清楚 Redo Log 和 Undo Log 的区别,走出常见的误区,省略了底层细节。

Redo Log 和 Undo Log 并不是 MySQL 发明的,而是来自 ARISE 理论(Algorithms for Recovery and Isolation Exploiting Semantics,基于语义的恢复与隔离算法),现代主流关系型数据库在事务实现上都受到了该理论的影响。

Redo Log 和 Undo Log 是实现方式,而目的是为了实现原子性(A)和持久性(D)。A 和 D 是手段,最终目的是实现一致性(C),这里的一致性可以理解为是业务上的一致性。

只有当事务的所有数据都正确写入磁盘,原子性和持久性才算实现。但由于写入磁盘过程有可能崩溃(数据库程序崩溃、硬件故障等等),所以在客观存在磁盘写入的中间状态。将磁盘从中间状态恢复到写入前的正确状态,是实现原子性和持久性要考虑的主要问题。

将所有操作都持久化到日志中,只有当日志完全写完时,才修改数据库数据。这样就解决了上面的问题(Committing Log)。

日志写完后,不立刻修改数据库可以吗?答案是肯定的,只要日志完整,就可以保证持久化,可以自由选择修改数据库的时机,这样 IO 就有了优化空间。这种情形叫做 FORCE/NOT FORCE,主流的数据库大多是 NOT FORCE。

日志写完前,修改数据库可以吗?可以,但会有问题。当遇到崩溃需要回滚或事务回滚时,因为日志可能并没有写完,所以没有办法回滚提前写入的数据,这部分数据就变成了脏数据。
引入 Undo Log 可以解决这个问题。Undo Log 记录了变更的字段,以及变更前和变更后的值,数据库必须在写入 Undo Log 后变更数据。在日志写完前修改数据库,叫做 STEAL,反之是 NOT STEAL。

NOT-FORCE 和 STEAL 是性能最佳的组合,是数据库的设计方向。

Redo Log 实现了 NOT FORCE, Undo Log 实现了 STEAL。
Redo Log 保存了数据库操作记录,Undo Log 保存了数据变更。
Redo Log 侧重于程序崩溃后的恢复,Undo Log 还可以应用于事务回滚。

当遇到崩溃需要恢复时:

  1. 重做 Redo Log,将数据库恢复到崩溃前的状态。(注意,此时可能有些数据已经变更,但没有写入 Redo Log,所以还需要第二步)
  2. 重做 Undo Log,还原提前写入的数据,此时数据库保证了前后的一致性。

posted on 2024-03-11 16:46  爱吃橘子的胖达  阅读(28)  评论(0编辑  收藏  举报