数据库恢复

数据库恢复

查询和更新数据库时,由于某些问题( ( 故障) ) 发生可能会导致数据库被破坏或影响数据库中数据的一致性。

数据库恢复技术将数据库从错误状态恢复到某个一致状态,它是数据库可靠性的保证。


1. 常见问题

  1. 事务故障(内部原因)
  • 错误输入,运算溢出等
  1. 介质故障(物理原因)
  • 局部故障,磁盘扇区的奇偶校验法可检测
  • 严重故障(磁盘无法访问),RAID模式,备份、冗余分布
  • 磁盘中的数据丢失
  1. 系统故障(其他原因)
  • OS错误、断电等(外部原因)
  • 日志记录(分离的、非易失的日志中记录数据库更新,必要时候恢复)
  • -主存中的临时数据丢失

2. 恢复

存在系统其他位置的冗余数据进行恢复


2.1 冗余数据

  1. 日志
  2. 数据备份

3. 中断的事务

在数据库恢复时候,对故障发生时候对已提交的事务进行重做Redo,对未提交的事务进行撤销Undo,保证所有事物的原子性。
所以,恢复处理中第一个任务就是将所有的事物划分为已提交事务未提交事务

事务具有ACID四个性质,其中原子性。
日志是一个日志记录的序列,每个日志记录会记录事务的操作(开始、更新、提交和中止等),所以日志的体量很大。


3.1 日志记录形式

事务开始
事务提交
事务撤销
事务撤销
undo日志中的更新:<T, Y, OldV>
redo日志中的更新:<T, Y, NewV>
T:表示事务 ,X:数据元素


3.1.1 Undo 日志的恢复

做完事务T之前没做完的操作(事务T在commit或Abort之前的操作),然后进行事务撤销

如果事务T 的Commit 日志记录已到达磁盘,该事务一定已经完成

  1. 对每一个更新操作都生成一条undo 日志记录
  2. 如果事务改变了数据库元素x , 那么日志记录必须在x 的新值写回磁盘之前写到磁盘 (write ahead logging, WAL) ;
  3. 如果事务提交,则其Commit 日志记录必须在事务改变的所有数据库元素已写到磁盘后再写磁盘。

Redo操作

  1. 反向扫描日志文件 ,确认未完成的事务集合S ,即有<Ti, start> ,但没有<Ti, commit> ( 或<Ti, abort>)
    日志记录的事务集合
  2. 在扫描过程中,对每一条日志记录<Ti, X, v> 做:
    (1) 如果Ti \in S ,则 write (X, v) output (X) ;
  3. 对每一个事务Ti \in S ,增加<Ti, abort> 日志记录
  4. 刷新日志,即Flush Log

Flush Log

  • 任务:让缓冲区管理器 强制 将发生了修改的日志记录 写到磁盘

3.1.2 Redo 日志的恢复

只要日志中没有<commit, T> 记录,那么事务T 对数据库所做的更新就都没有写到磁盘上。

Redo日志规则

  1. 对每个事务中的更新操组都产生一条redo 日志记录( 包含新值,形如<Ti, X, newvalue> )
  2. 在修改磁盘上的任何数据库元素x 之前,要保证所有与x 的这一修改相关的日志记录,包括 记录,都必须先写到磁盘。
  3. 提交时同时刷新日志,即Flush Log 。
  4. 在数据库被刷新后,增加一条<Ti, end>

Redo操作

  1. 正向扫描日志文件 ,确认已提交的事务集合S ,即在日志中有<Ti, commit> ( 但没有<Ti, end>) 日志记录的事务集合
  2. 在扫描过程中,对每一条日志记录<Ti, X, v> 做:
    (1) 如果Ti \in S 则 Write(X, v), Output(X)
  3. 对每个Ti \in S, 增加日志记录<Ti, end>
  4. 刷新日志,即Flush Log

3.2 Undo|Redo日志恢复

  • 正向扫描日志,确定已提交事务集合 和 未提交事务集合;
  • 反向扫描日志,Undo所有未提交事务;
  • 正向扫描日志,Redo所有已提交的事务。

4. 检查点技术

每次恢复都检查整个日志好浪费时间哦,又不是所有的事务都需要重新处理,事务只要在日志上有commit的记录,那就不需要处理它了嘛。

怎么搞???

周期性的在日志上做标记(检查点),检查点之前的日志记录在恢复的时候就不用管了嘛!!!

  • 所有在检查点之前执行的事务都已经完成,并写回磁盘。恢复时不需要撤销。
  • 在恢复中,确定所有未完成事务的处理,只需反向扫描日志至发现 记录时止。

4.1 非静止检查点

简单的检查点技术在效果上相当于在进行检查点是必须关闭系统。由于活跃的事务可能需要较长的时间来
提交或中止,在用户看来系统似乎停止了。

特点:

  • 让系统处于检查点时仍允许新的事务进入;
  • 唯一的代价是恢复时非静止检查点前的某些日志记录可能需要检查。

4.1.1 undo

步骤:

  • 写入日志记录<Start CKPT(T1,…,Tk)> ,其中T1,…,Tk 为所有活跃事务的标识。
  • 等待T1,…,Tk 中的每一个提交或中止,但允许其他事务开始。
  • 当T1,…,Tk 都完成时,写入日志记录<END CKPT> 并刷新日志

4.1.2 redo

特有问题:Redo 日志中被修改的数据写到磁盘的时间可能比事务提交的时间晚得多。

定期进行数据备份

在这里插入图片描述