必须先重做再回滚:重做阶段依据WAL日志将已提交但未落盘的修改追加到数据页,建立最新一致视图;回滚阶段据此识别并撤销未完成事务的脏写,确保原子性与持久性。
数据库崩溃后,恢复过程核心在于保证事务的原子性和持久性,主要依靠日志(WAL,Write-Ahead Logging)驱动两个关键阶段:重做(Redo)和回滚(Undo)。顺序不能颠倒——必须先重做,再回滚。
重做阶段从检查点(Checkpoint)开始,扫描日志中所有在检查点之后、崩溃发生前已写入日志但尚未刷入数据页的已提交事务操作(INSERT/UPDATE/DELETE),按日志顺序重新应用到数据页上。
重做完成后,系统识别出那些在崩溃时仍处于“活动状态”(未提交也未中止)的事务,并利用undo日志(或回滚段)将它们对数据页所做的修改全部撤销。
如果先回滚,可能把其他已提交事务的中间结果误删——因为崩溃时多个事务并发修改,数据页可能混杂了已提交和未提交的变更。只有先通过重做,把所有已提交的变更“追齐”到一致状态,才能准确识别哪些修改真正属于未完成事务,从而安全回滚。
现代SQL引擎(如PostgreSQL、SQL Server、Oracle)均以该模型为基础,辅以以下设计确保可靠性: