文章目录
数据库恢复
查询和更新数据库时,由于某些问题( ( 故障) ) 发生可能会导致数据库被破坏或影响数据库中数据的一致性。
数据库恢复技术将数据库从错误状态恢复到某个一致状态,它是数据库可靠性的保证。
1. 常见问题
- 事务故障(内部原因)
- 错误输入,运算溢出等
- 介质故障(物理原因)
- 局部故障,磁盘扇区的奇偶校验法可检测
- 严重故障(磁盘无法访问),RAID模式,备份、冗余分布
- 磁盘中的数据丢失
- 系统故障(其他原因)
- OS错误、断电等(外部原因)
- 日志记录(分离的、非易失的日志中记录数据库更新,必要时候恢复)
- -主存中的临时数据丢失
2. 恢复
存在系统其他位置的冗余数据进行恢复
2.1 冗余数据
- 日志
- 数据备份
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 日志记录已到达磁盘,该事务一定已经完成
- 对每一个更新操作都生成一条undo 日志记录
- 如果事务改变了数据库元素x , 那么日志记录必须在x 的新值写回磁盘之前写到磁盘 (write ahead logging, WAL) ;
- 如果事务提交,则其Commit 日志记录必须在事务改变的所有数据库元素已写到磁盘后再写磁盘。
Redo操作:
- 反向扫描日志文件 ,确认未完成的事务集合S ,即
有<Ti, start>
,但没有<Ti, commit> ( 或<Ti, abort>)
日志记录的事务集合 - 在扫描过程中,对每一条日志记录<Ti, X, v> 做:
(1) 如果Ti ∈ \in ∈ S ,则 write (X, v) output (X) ; - 对每一个事务Ti
∈
\in
∈ S ,增加
<Ti, abort>
日志记录 - 刷新日志,即
Flush Log
Flush Log
- 任务:让缓冲区管理器 强制 将发生了修改的日志记录 写到磁盘
3.1.2 Redo 日志的恢复
只要日志中没有<commit, T> 记录,那么事务T 对数据库所做的更新就都没有写到磁盘上。
Redo日志规则:
- 对每个事务中的更新操组都产生一条
redo 日志记录
( 包含新值,形如<Ti, X, newvalue> ) - 在修改磁盘上的任何数据库元素x 之前,要保证所有与x 的这一修改相关的日志记录,包括 记录,都必须先写到磁盘。
- 提交时同时刷新日志,即Flush Log 。
- 在数据库被刷新后,增加一条<Ti, end>
Redo操作:
- 正向扫描日志文件 ,确认已提交的事务集合S ,即在日志中有<Ti, commit> ( 但没有<Ti, end>) 日志记录的事务集合
- 在扫描过程中,对每一条日志记录<Ti, X, v> 做:
(1) 如果Ti ∈ \in ∈ S 则 Write(X, v), Output(X) - 对每个Ti
∈
\in
∈ S, 增加日志记录
<Ti, end>
- 刷新日志,即
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 日志中被修改的数据写到磁盘的时间可能比事务提交的时间晚得多。
定期进行数据备份