数据库(五) 数据库恢复系统

本文最后更新于:2023年2月28日 下午

数据库恢复机制(recovery schemes) 可以记录事务的执行(e.g. log in DBS),保证事务的原子性、持久性和数据库系统的高可用性(high avaliability)。备份(backup)是另一个确保数据库系统高可用性的途径。

1. 故障分类

故障分类 (Classification of failure)

  1. 事务失败(Transaction failure)

    • 逻辑错误(logical errors)

      代码发生错误,事务无法正确执行

    • 系统错误(system errors)

      数据库系统由于系统中的某些条件而无法实现活动事务或必须终止活动事务时发生的错误

  2. 系统崩溃(System Crash)

    有些问题可能会导致系统意外从外部停止,并可能导致系统崩溃。 例如,电源故障(power failure)

    非易失存储(non-volatile storage) 内容不会被系统崩溃损坏

  3. 磁盘故障(Disk Failure)

2. 存储分类

按照存储介质(storage medium)可以将存储分为以下三种:

  • 易失存储 (volatile storage)

    系统崩溃时损坏

    e.g. 主存(main memory)、缓存(cache memory)

  • 非易失存储/永久存储 (non-volatile storage)

    系统崩溃时不损坏

    e.g. 磁盘(disk)、闪存(flash memory)、磁带(tape)

  • 可靠存储/稳定存储 (stable storage)

    认为能够不再任何故障中损坏的理想形式

    目前通过在多个非易失存储上备份近似实现

3. 事务中数据存取过程

数据库中事务对数据项目的读写指令涉及以下三个区域:

  • physical blocks

    存在于磁盘中

  • buffer blocks

    存在于主存中,将被暂时置于disk buffers/system block buffers上

  • private work-area/local biffer

    存在于主存中,每个事务都有私有工作区,防止读写的数据项的副本

其过程涉及:

  • input(X):将数据项从磁盘的physical block中转存至主存的buffer block
  • output(X):将数据项从主存的buffer block转存至磁盘的physical block,覆盖原physical block数据
  • read(X):事务读取buffer block中的数据项,对private work-area中的数据项副本进行赋值。如果buffer block中没有数据项,则触发input(X)
  • write(X):事务将private work-area数据项的值赋给buffer block数数据项

如在事务为active状态时,所有对数据库数据的更改都暂存于主存的buffer block中而未被写入磁盘。

3. 数据库恢复机制

基于日志的恢复(log-based recovery)

日志(log)

日志记录了每一更改数据库数据指令(log records),存储在可靠存储中

1
2
3
4
事务开始 <Ti start>
事务部分提交 <Ti commit>
事务中止 <Ti abort>
事务将数据项X的值V1更新为V2 <TI X,V1,V2>

基于日志的恢复有两个修改方案:

  1. 延迟数据库修改 (deferred database modification)

    事务在提交之前不修改数据库,所有数据项的更新值存储于buffer block中。

    • 日志只记录更新后的值 <Ti X V2>
    • redo(Ti):基于日志,恢复更新后的数据
      • 事务部分提交后故障,日志只存在<Ti start>记录,无<Ti commit>记录,数据库不更新,日志忽略
      • 事务部分提交后故障,日志存在<Ti start><Ti commit>记录,回滚redo(Ti)

    实例

  2. 即时数据库修改 (immediate database modification)

    事务在活动状态时发生数据库修改,数据项更新值直接更新在磁盘的physical block中。

    • 日志记录更新前后的值 <Ti X V1 V2>
    • undo(Ti):基于日志,恢复更新前的数据
      • 事务部分提交前故障,日志只存在<Ti start>记录,无<Ti commit>记录,回滚undo(Ti)
      • 事务部分提交后故障,日志存在<Ti start><Ti commit>记录,回滚redo(Ti)

    undo

    redo

    实例

检查点(checkpoint)

由于基于日志的恢复每次翻阅日志费时,且部分事务更新结果已写入磁盘时不需要再进行redo,我们引入检查点(checkpoint)。

检查点(checkpoint)

  1. 将buffer block中的所有日志记录写入stable storage

  2. 将buffer block中的所有更新数据写入磁盘

  3. 在日志中增加日志记录 <checkpoint L>

    L是事务列表,包含所有在checkpoint之后仍处于激活状态的事务

  4. L中的事务