2

根据我对 ARIES 算法的理解,要支持 ACID 事务,必须使用 WAL(预写日志):所有写入都会被记录。

据说它使数据库能够在崩溃之前回滚由未提交事务所做的更改。

对于每次写入,我们都会记录有关实际写入的信息(如何重做,如何撤消)。

在恢复阶段,我们分析日志以执行 REDO 操作:

  • 我们阅读了日志条目
  • 我们将更改应用到数据库
  • 我们将日志条目设置为完成

然后,为了执行 UNDO,写入新的日志条目(因为它毕竟是写入),然后在检查点期间将更改应用于数据库。

在检查点期间,我想我们只是对所有提交的条目执行重做。

我还没有找到任何有关以下情况的信息:

  • 检查点期间发生崩溃
  • 在重做阶段、更改应用到数据库之后以及更新日志之前/期间将其设置为完成时发生崩溃

在这些情况下,一些更改已应用到数据库,但未反映在日志中,从而使数据库处于不一致状态。

注意:这是我用来了解更多关于 ACID 事务和 ARIES 算法的一些链接:

我目前正在阅读 SQLite 的源代码,以了解整个事情是如何实现的。

提前感谢您对此主题的任何澄清。

4

1 回答 1

2

在 REDO 期间,读取日志并根据需要修改数据。如果在重做期间发生崩溃,那么下一次恢复将再次运行重做。一些在第一次恢复尝试时修改数据的日志记录将是无操作的,因为数据修改已保存。其他将不会被保存,将再次“重做”。

检查点仍然是一个事务操作。在内存中保存数据,然后最后将检查点日志记录写入日志中。如果在检查点期间发生崩溃,则只能在写入检查点记录之前发生。崩溃恢复后再次运行并从 REDO 开始(因为没有新检查点的记录)。以上几点适用,REDO可以重复运行。一些日志记录将是无操作的,因为数据更改已经保存,一些将再次“重做”。

UNDO 通过生成和写入补偿日志记录来工作。如果在 UNDO 期间发生崩溃,那么在下一次恢复时,还有一个要分析的记录和 REDO(补偿记录)。此后 UNDO 崩溃恢复将在最后一次成功的 UNDO 日志记录保存后开始运行它的 UNDO 阶段。也就是说,如果原始日志在一个未提交的事务中包含两个操作,比如 OP1 和 OP2,然后启动 UNDO,它会写入补偿 UNDO-OP1 并崩溃。然后恢复将从 OP2 开始 UNDO,因为对于 OP1,日志中已经有一个补偿记录(UNDO-OP1)。

在正确实施的 ARIES 中,从来没有任何不一致的窗口。

于 2017-07-01T05:48:25.083 回答