补偿日志的重做信息对应于日志条目的撤消信息,这些信息使得在撤消阶段需要创建日志条目。
在我看来,CLR重做信息与触发它们的日志的撤销信息是一样的。
但是,它们是否应该有重做信息,以便在恢复过程中断时取消已执行的撤消操作?
让T2成为一个失败的交易:
<#55, T2, P3, J=J+9, J = J-9, #53>J=J+9是redo-op,J= J-9是撤销-op.
现在,在重做阶段追加到日志文件的CLR应该是:
<#56, T2, J=J-9,__, #53>将J=J-9作为CLR中的重做信息,作为原始日志条目的撤销操作。如果恢复中断,日志条目#56将在重做阶段执行。
CLR的目的是确保重新启动恢复过程并再次运行它总是会导致相同的结果。在重做阶段运行J=J-9操作如何确保这一点?
有人能给我解释一下吗?
发布于 2021-09-12 06:19:51
在正常操作期间,补偿日志记录(CLR)不会写入日志。它们是在处理回滚时产生的,要么是应用程序请求的,要么是崩溃造成的。因为它们的唯一使用是在回滚过程中,所以它们只需要保存足够的信息来执行该操作,即示例中的J=J-9。每个CLR通过LSN引用与其相应的原始日志记录配对。
恢复的重做阶段的目的是将数据库返回到崩溃时的状态。如果在恢复过程中的一半时间发生崩溃,那么第二个恢复的重做阶段应该像第一次恢复的一半一样离开db。第二个恢复的重做阶段处理由第一个恢复的撤销阶段编写的CLR。因为CLR链接到原始更新日志记录,所以知道最后处理的CLR会告诉第二个恢复的撤销阶段,哪个日志记录要跳转到哪个日志记录,这样它就可以完成回滚。
要使用给定的示例,第一个恢复的撤消阶段将处理日志记录#55's撤消操作(J = J-9)并创建CLR #56。然后,它将返回到前一个链接记录(#53)。假设我们在它被处理之前就坠毁了。第二个恢复阶段将处理CLR #56's操作。如果这是最后一个CLR,那么第二个恢复的撤销阶段将按照链接返回到#53,然后从那里完成回滚。在第二次和以后的恢复期间,#56有效地取代#55。
那为什么还要为这些烦恼呢?为什么第二次复苏不能像第一次复苏那样简单呢?因为白羊座假设缓冲区管理器使用偷,所以没有强制策略。在第一次恢复期间,可能会部分回滚页面,然后从缓冲池中交换。因此,第二次恢复不是从与第一次恢复相同的持久化状态开始的,因此不能简单地第二次执行相同的操作。
https://dba.stackexchange.com/questions/299406
复制相似问题