You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数据库恢复UNDO阶段Compensation Log Records(CLR)运行逻辑疑问

补偿日志记录(CLR)重做逻辑的核心原理

核心前提先明确

首先要先理清数据库故障恢复两个阶段的底层规则:

  • 重做(REDO)阶段:所有日志中记录的已提交/未提交/中止事务的操作,只要没有确认刷入磁盘,全部按顺序重放,保证磁盘数据和日志记录的所有操作执行后的状态完全对齐
  • 撤销(UNDO)阶段:仅处理未提交/中止的事务,对这些事务未被回滚的操作执行逆操作,每完成一条原日志的回滚,就写入一条CLR标记该操作已回滚,同时记录下一条需要回滚的日志LSN

结合你给出的场景解释逻辑

你给出的原日志<#55, T2, P3, J=J+9, J = J-9, #53>对应的是事务T2执行了J=J+9的更新操作,J=J-9是该操作的逆操作,也就是回滚时需要执行的逻辑。
CLR<#56, T2, J=J-9,__, #53>里的三个核心字段含义是:

  1. J=J-9:已经完成执行的回滚操作
  2. 空字段:CLR本身是回滚操作的记录,不需要再有逆操作(回滚不能被二次回滚)
  3. #53:T2下一条需要回滚的日志的LSN,相当于标记LSN为#55的原日志已经完成回滚,不需要再处理

恢复中断后重跑的一致性保证逻辑

我们用J初始值为10的具体数值演示全流程:

  1. 初始状态:J=10,T2执行J=J+9后J变为19,写完日志#55后数据库崩溃,更新后的数据页还没刷入磁盘
  2. 第一次启动恢复:
    • REDO阶段重放日志#55的J=J+9,J被更新为19
    • UNDO阶段处理中止事务T2,执行逆操作J=J-9,J回到10,写入CLR#56并落盘
    • 此时回滚后的J=10还没刷入磁盘,数据库再次崩溃,恢复中断
  3. 第二次重启恢复(也就是你说的重跑场景):
    • REDO阶段按顺序重放所有未落盘的日志操作:先执行#55的J=J+9(J变为19),再执行CLR#56的J=J-9(J回到10)。这两步执行完后,不管之前的回滚操作有没有刷盘,当前J的状态已经和「#55已完成回滚」的状态完全对齐
    • 进入UNDO阶段后,读取T2的最新日志是CLR#56,直接取其中记录的下一条待回滚LSN#53,完全跳过#55的处理,不会重复执行J=J-9导致J变成1

核心误区澄清

CLR不需要携带抵消UNDO的信息,恰恰相反,CLR的重做信息就是要把已经完成的UNDO操作固化到日志里:恢复中断后,REDO阶段重放CLR的操作,本质是把之前执行到一半的UNDO进度先还原回来,避免UNDO阶段重复回滚已经处理过的操作,不管恢复中断多少次,最终回滚的结果都是一致的。

内容的提问来源于stack exchange,提问作者Sigmund

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 06:06:04