6 数据库恢复

学习笔记
作者: MingXiao

6.1 数据库故障

  • 事务故障:资源冲突导致死锁
  • 系统故障(软件)
  • 磁盘故障(硬件):或者其他非易事存储介质
  • 自然灾害。。。

6.2 缓冲池策略

数据库系统产生错误,在RAM中的数据没写到磁盘就消失了

如何恢复

  • 撤销未完成(ROLLBACK)修改
  • 重做已完成(COMMIT)修改

未提交事务

  • 允许修改磁盘:STEAL,缓冲池效率高(占用完就消除了)
  • 不允许:No-STEAL,效率低,并发低(一直占用)

以提交事务

  • 强制修改:FORCE,I/O效率低(占用I/O接口,带宽满了就得等)
  • 不强制修改:No-FORCE,效率高

上面有4种组合

考虑下面的故障,四种组合的恢复策略分别是

No-STEAL AND FORCE

执行效率低,但是恢复最友好,T1T2都不需要任何操作

NO-STEAL AND No-FORCE

需要重做T1

STEAL AND FORCE

需要撤销T2

STEAL AND No-FORCE

执行效率高但是恢复难度高,T1重做,T2撤销,最麻烦

6.3 数据库日志

日志记录的序列,顺序写入磁盘,不会修改;只能写不能改

6.3.1 Undo回滚日志

格式:<T,X.v_old>,分别是事务标识符,数据项,数据项修改的值

产生时机:T修改X的值(W(X))时产生

作用:用于回滚

6.3.2 Redo重做日志

格式:<T,X.v_new>,分别是事务标识符,数据项,数据项修改的值

产生时机:T修改X的值(W(X))时产生

作用:用于重做

6.3.3 预写日志WAL

日志必须在磁盘中才有效,且必须比数据先写入磁盘(Write Ahead Logging)

日志写回磁盘的顺序和生成的顺序一致,且只有<T,commit>写入磁盘后,事务T才算结束

因此事务执行前必先写日志,然后才能做缓冲池策略,恢复时就看日志

6.4 故障恢复机制

6.4.1 事务分类

分为三类:

  • 已完成,存在<T,start>和<T,commit>,没写入磁盘需要redo
  • 不完整,只有<T,start>,已经写入磁盘需要undo
  • 已终止,存在<T,start>和<T,rollback>,不需要恢复

6.4.2 No-STEAL AND FORCE

使用影子拷贝法,将原始数据拷贝到另一个数据库(再开空间),修改完后,事务提交完才提交到原始数据库

空间开销大,不实用

6.4.3 STEAL AND FORCE

需要WAL和Undo,不需要Redo,使用Undo日志,恢复流程如下

  1. 找到未提交的事务
  2. 回滚这些事务
  3. 写入<T,rollback>

恢复时,从后向前看日志一次,每条记录有以下动作

  • <T,commit>,将T标记为已提交,不操作
  • <T,rollback>,将T标记,不操作
  • <T,X,v_old>,如果T没有任何标记,那么将X恢复为v_old
  • <T,start>,如果T没有标记(不完整),在最下方下入<T,rollback>

6.4.4 No-STEAL AND No-FORCE

需要WAL和Redo,不需要Undo,使用Redo日志,恢复流程如下

  1. 找到提交的事务
  2. 重做这些事务
  3. 写入<T,commit>

恢复操作,整个日志顺序扫描两遍

  1. 第一次,记录所有commit和rollback并标记
  2. 第二次,<T,X,v_new>,根据T的标记,commit就将X写为v_new,rollback就不管
  3. 对于<T,start>,没有标记的,那么就写一个rollback

6.4.5 STEAL AND No-FORCE

需要WAL,Redo,Undo,使用混合日志,恢复流程就是上面两个的混合

记录流程

  • 开始事务,<T,start>
  • 修改事务,<T,X,v_old,v_new>
  • 提交事务,<T,commit>
  • 终止事务,<T,rollback>

恢复流程

  1. 第一次顺序扫描,记录所有的commit和rollback

    有start而没有commit/rollback,则需要撤销;有start且有commit,需要重做

  2. 第二次顺序扫描,重做commit的T,也叫重放历史

  3. 第三次逆序扫描,**撤销没有标记(不完整)**的T

6.5 检查点

只会读取检查点之后的日志

6.5.1 全量检查点

设置流程

  1. 停止所有事务
  2. 将RAM没写的数据写到磁盘
  3. 记录检查点
  4. 恢复事务

6.5.2 涉及检查点的恢复

  • 检查点之前完成(commit/rollback)的事务不用管
  • 检查点之后的commit需要redo
  • 所有未完成的事务需要undo


Comments