“Undo 按 LSN 逆序遍历 loser 的日志链,撤销可撤销更新,并为每次撤销写 补偿日志记录。CLR 的 指向下一项待撤销工作;事务完全回滚后写 END。三阶段次序先重建精确崩溃现场,…”
形式陈述 ​
补偿日志记录(CLR)是在撤销某条更新时追加的 WAL 记录。它描述“撤销动作对页面做了什么”,使这次补偿在恢复中可以 redo;同时标记为不可再次 undo。典型字段包括事务 ID、页 ID、补偿的 redo 信息、prevLSN,以及
后者指向该事务日志链中下一条仍应撤销的原始记录。若被撤销记录的前驱就是下一目标,undoNextLSN 可取其 prevLSN;部分回滚或已有 CLR 则可能跨过一段已经处理的日志。
ARIES 恢复算法在 Undo 阶段先写 CLR,再让相应页面修改遵守 WAL。重启 Redo 会重放尚未落盘的 CLR;之后 Undo 遇到 CLR 时沿 undoNextLSN 继续,而不是把补偿本身反向执行。这样“撤销一次更新”在任意多次恢复重启中至多保留一个逻辑结果。
CLR 与普通 update log 的不对称是刻意的。普通更新同时需要 redo 与 undo 能力;CLR 已经代表回退决定,若再 undo 它,就会重新引入原先应删除的更新,造成恢复振荡。
写 CLR 与执行页面补偿共同组成一次受 WAL 保护的恢复步。CLR 必须先于含补偿结果的数据页稳定;否则页面已经回退、日志却不知道该步完成,再次恢复可能从错误位置重复普通 undo。反过来,CLR 已稳定而页面未写盘是允许的,Redo 会补做。
直觉
把回滚想成沿面包屑倒着走。每走回一步,CLR 不只写下“我来过”,还留下下一块应找的面包屑。途中再次断电时,恢复者先确认已经走完的补偿是否落到页面,再从指针处继续,不必从事务末尾重新猜。
“补偿”在这里是存储级撤销动作,不是业务 saga 中发送退款、撤销预约的语义补偿。后者可能失败、产生新外部效果,也未必是原操作的逆函数。
CLR 像一张只能向前兑现的回程票。它记录已经决定回退哪一站,却不会让恢复者把回程再当成新的去程。undoNextLSN 则把整条原日志链压成尚未完成的后缀,避免每次重启从尾端重新搜索。
例子与边界
事务
LSN 50 <- LSN 70 <- LSN 90
恢复先撤销 LSN 90,并写入 CLR 100,其中 undoNextLSN=70。补偿页面刚写入内存,系统再次崩溃。第二次重启的 Redo 会在需要时重放 CLR 100;Undo 读到它后直接把 70 放入待撤销集合,不会再次撤销 90,也不会“撤销 CLR 100”使 LSN 90 的效果复活。
接着撤销 70 可写 CLR 110,指向 50。若 70 属于一次已经完成的局部回滚,先前 CLR 可能让指针直接跳到 50;这正是 undoNextLSN 比盲目跟随 prevLSN 更精确的地方。
CLR 仍需幂等页面操作和 pageLSN 检查。若补偿逻辑依赖一次性外部调用,简单 redo CLR 可能重复副作用;这类动作不能未经协议封装就作为普通页面恢复记录。
CLR 也可能比原始物理更新更“逻辑”。例如删除一次 B-tree 插入时,页面结构已因并发分裂改变,补偿记录需要描述可在当前结构上重做的动作,并由锁或 latch 规则保证安全。不能假定每次 undo 都只是把固定字节抄回原位置。
推论与应用
CLR 使恢复本身成为可恢复事务:Undo 的每一步都有日志见证,恢复期间崩溃不会让工作无界重复。它也支持 savepoint 和部分回滚,因为指针可以指定本次撤销的停止位置,再让事务继续执行。
日志检查工具应验证 CLR 不进入普通 undo 分支、undoNextLSN 沿事务历史严格后退,并且补偿页落盘前 CLR 已稳定。只检查“CLR 数量等于 update 数量”没有意义,因为 winner 无需 CLR,部分回滚和跳跃链也会改变数量。
Undo 调度常用按 LSN 从大到小的优先队列合并多个 loser。遇到普通记录便撤销并压入其前驱,遇到 CLR 则压入 undoNextLSN;到达事务 begin 后写 END。这个有限下降过程给出了恢复终止的直接度量。
参考资料
- C. Mohan et al., “ARIES: A Transaction Recovery Method Supporting Fine-Granularity Locking and Partial Rollbacks Using Write-Ahead Logging,” ACM Transactions on Database Systems 17(1), 1992, pp. 94–162。
- Jim Gray and Andreas Reuter, Transaction Processing: Concepts and Techniques, Morgan Kaufmann, 1992, Ch. 11。
- Raghu Ramakrishnan and Johannes Gehrke, Database Management Systems, 3rd ed., McGraw-Hill, 2003, recovery chapter。