根据我对ARIES算法的理解,为了支持ACID事务,必须使用WAL(Write Ahead Logging):记录所有写入。
据说它使数据库能够在崩溃前回滚未提交事务所做的更改。
对于每次写入,我们都会记录有关实际写入的信息(如何重做它,如何删除它)。
在恢复阶段,我们会分析日志以执行REDO操作:
然后,为了执行UNDO,会写入一个新的日志条目(因为它毕竟是一个写入),然后在检查点期间将更改应用于数据库。
在检查点期间,我想我们只是为所有已提交的条目执行REDO。
如果出现以下情况,我还没有发现任何信息:
在这些情况下,某些更改已应用于数据库,并且不会被日志反映,从而使数据库处于不一致状态。
注意:以下是我用来了解ACID交易和ARIES算法的一些链接:
我目前正在阅读SQLite的源代码,以了解整个事情是如何实现的。
提前感谢您对此主题的任何澄清。
答案 0 :(得分:1)
在REDO期间,将读取日志,并在需要时修改数据。如果在REDO期间发生崩溃,则下一次恢复将再次运行REDO。在第一次恢复尝试时修改数据的某些日志记录将是no-op,因为已保存数据修改。其他将不会保存,将重做'重做试。
检查点仍然是交易操作。在内存中保存数据,然后在最后一个检查点日志记录写入日志中。如果在检查点期间发生崩溃,则只能在写入检查点记录之前发生崩溃。崩溃恢复再次运行并以REDO开始(因为没有新检查点的记录)。以上几点适用,REDO可以重复运行。一些日志记录将是no-op,因为数据更改已经保存,一些将被重做'试。
UNDO正致力于生成和编写补偿日志记录。如果在UNDO期间发生崩溃,那么在下次恢复时,还有一个要分析的记录和REDO(补偿记录)。此后UNDO崩溃恢复将在保存最后一次成功的UNDO日志记录之后运行它的UNDO阶段 。也就是说,如果原始日志在未提交的事务中包含两个操作,比如说OP1和OP2然后启动UNDO,它会写入补偿的UNDO-OP1并崩溃。然后从OP2开始恢复UNDO,因为对于OP1,日志中已有补偿记录(UNDO-OP1)。
正确实施的ARIES中永远不存在任何不一致的窗口。