如果Aries算法已经知道在分析阶段后要撤消哪些事务,为什么它会在撤消之前应用重做?
我知道(认为)这与 Lsn 数字和保持一致性有关,因为鉴于磁盘上刷新的数据可能与崩溃时撤消事务不同(由于脏页面),但我找不到这个问题的任何"正式"答案(至少我可以理解)。
因为即使提交事务,缓冲区上也可能有未刷新的页面。ARIES在缓冲区管理器中使用无力。重做会使事务表和脏页表恢复到崩溃时的状态。因此,成功的事务可以反映到稳定存储中。
简短回答:
我们需要在重做传递中重复所有历史记录崩溃,以便在执行撤消传递之前确保数据库一致性。
长答案:
恢复算法ARIES,为了保证DBMS的原子性和持久性属性,执行3次:
- 分析通过:查看需要执行的操作(播放日志前置)
- 重做传递:确保磁盘反映日志中但不在磁盘上的任何更新,包括属于最终将回滚的事务的更新。通过这种方式,它可以确保我们处于一致的状态,这将允许逻辑撤消。
- 撤消传递:删除任何丢失事务的操作
撤消数据日志是逻辑的,而重做数据日志是物理的:
- 我们必须进行物理重做,因为我们不能保证数据库处于一致状态(因此,例如,记录"将值 X 插入表 Y"可能不是一个好主意,因为 X 可能会反映在索引中而不是表中,反之亦然,以防插入时发生崩溃)
- 我们可以进行逻辑撤消,因为在重做之后我们知道事情是一致的。事实上,我们必须执行逻辑 UNDO,因为我们只撤消一些操作,并且表单的 UNDO 的物理日志记录,例如,"索引 y 的拆分页 x"在索引管理或固定维护方面可能不再是正确的做法。在重做过程中我们不必担心这一点,因为我们重复历史记录并重放所有内容,这意味着上次对数据库所做的任何物理修改仍然是正确的。
源
不知道白羊座是什么,但假设它与其他数据库相同:
从一些基本备份开始,应用重做日志,这基本上意味着在备份之后但在崩溃之前发生的所有数据更改语句被应用。没有它,您将丢失自上次备份以来发生的一切。
完成后,所有未完成的事务都将回滚,因为没有人可以拾起这些事务来完成它们。
您希望返回到失败状态,以便准确确定需要撤消哪些事务。我想到的一个例子是连续失败。从崩溃中恢复时精确地出现故障。在恢复期间,您将操作写入日志。如果在恢复过程中失败,您将重做日志中的所有操作(甚至是上次尝试期间写入的撤消操作!!
它提供了一个简单的算法,因为您不必处理特殊情况和特殊情况的特殊情况。可以保证,在恢复期间发生任何数量的崩溃后,我们将返回到与恢复期间没有崩溃相同的状态。
如果您不支持记录级锁定,则可以使用仅重做获胜者事务的选择性重做。 否则,最好在撤消之前重复历史记录(全部
您可以考虑在重做和撤消期间真正执行的操作。根据退出的日志,重做正在重复历史记录。相反,撤消是创建新的 CLR 日志记录。当系统崩溃时,日志包含有关未提交的 xact 的记录。如果不撤消它们,则不会有 CLR 日志记录,从而导致不一致。
ARIES的目标之一是简单。虽然重做后撤消可能不是必需的,但它使算法的正确性比在重做之前撤消的更复杂的方案更明显。
除了确保数据库一致且磁盘与崩溃发生之前完全相同(如 Franck Dernoncourt 回答的那样)之外,在撤消之前执行重做的另一个好处是:
恢复期间可能会发生故障。重做推进了整个"增量恢复"的进度,即,如果在重做或撤消期间发生故障,则下一次恢复可以拾取先前恢复(重做)剩余的内容并继续(如果在撤消之前执行重做)。
一个极端的情况是,如果撤消在重做之前执行,并且在撤消期间再次失败,则所有撤消都将徒劳无功。