数据库 - 恢复策略与数据库镜像

登记日志文件

基本原则
登记的次序严格按并行事务执行的时间次序
必须先写日志文件,后写数据库
写日志文件操作:把表示这个修改的日志记录
写到日志文件
写数据库操作:把对数据的修改写到数据库中

为什么要先写日志文件 (The Write-Ahead Log)
写数据库和写日志文件是两个不同的操作
在这两个操作之间可能发生故障
如果先写了数据库修改,而在日志文件中没有登记下这个修改,则以后就无法恢复这个修改了
如果先写日志,但没有修改数据库,按日志文件恢复时只不过是多执行一次不必要的UNDO操作,并不会影响数据库的正确性

事务故障的恢复

事务故障:事务在运行至正常终止点前被终止
恢复方法
由恢复子系统应利用日志文件撤消(UNDO)此事务已对数据库进行的修改
事务故障的恢复由系统自动完成,对用户是透明的,不需要用户干预

事务故障的恢复步骤

  1. 反向扫描文件日志(即从最后向前扫描日志文件),查找该事务的更新操作。
  2. 对该事务的更新操作执行逆操作。即将日志记录中“更新前的值” 写入数据库。
    插入操作, “更新前的值”为空,则相当于做删除操作
    删除操作,“更新后的值”为空,则相当于做插入操作
    若是修改操作,则相当于用修改前值代替修改后值
  3. 继续反向扫描日志文件,查找该事务的其他更新操作,并做同样处理。
  4. 如此处理下去,直至读到此事务的开始标记,事务故障恢复就完成了。

系统故障的恢复

系统故障造成数据库不一致状态的原因
未完成事务对数据库的更新已写入数据库
已提交事务对数据库的更新还留在缓冲区没来得及写入数据库
恢复方法
1. Undo 故障发生时未完成的事务
2. Redo 已完成的事务
系统故障的恢复由系统在重新启动时自动完成,不需要用户干预

1.正向扫描日志文件(即从头扫描日志文件)
重做(REDO) 队列: 在故障发生前已经提交的事务
这些事务既有BEGIN TRANSACTION记录,也有COMMIT记录
撤销 (Undo)队列:故障发生时尚未完成的事务
 这些事务只有BEGIN TRANSACTION记录,无相应的COMMIT记录
2. 对撤销(Undo)队列事务进行撤销(UNDO)处理
反向扫描日志文件,对每个UNDO事务的更新操作执行逆操作
即将日志记录中“更新前的值”写入数据库 

3. 对重做(Redo)队列事务进行重做(REDO)处理
正向扫描日志文件,对每个REDO事务重新执行登记的操作
即将日志记录中“更新后的值”写入数据库 

介质故障的恢复

恢复步骤
1. 装入最新的后备数据库副本(离故障发生时刻最近的转储副本) ,使数据库恢复到最近一次转储时的一致性状态。
对于静态转储的数据库副本,装入后数据库即处于一致性状态
对于动态转储的数据库副本,还须同时装入转储时刻的日志文件副本,利用与恢复系统故障的方法(即REDO+UNDO),才能将数据库恢复到一致性状态。

  1. 装入有关的日志文件副本(转储结束时刻的日志文件副本) ,重做已完成的事务,撤销未完成的事务。
    首先扫描日志文件,找出故障发生时已提交和未完成的事务的标识,分别将其记入重做队列和撤销队列。
    然后正向扫描日志文件,对重做队列中的所有事务进行REDO处理。反向扫描日志文件,对撤销队列中的所有事务进行UNDO处理。
    技术分享
    介质故障的恢复需要DBA介入
    DBA的工作
    重装最近转储的数据库副本和有关的各日志文件副本
    执行系统提供的恢复命令
    具体的恢复操作仍由DBMS完成

两个问题
搜索整个日志将耗费大量的时间
REDO处理:重新执行,浪费了大量时间
具有检查点(checkpoint)的恢复技术
在日志文件中增加检查点记录(checkpoint)
增加重新开始文件
恢复子系统在登录日志文件期间动态地维护日志
检查点记录的内容
1. 建立检查点时刻所有正在执行的事务清单
2. 这些事务最近一个日志记录的地址
重新开始文件(Oracle控制文件)的内容
记录各个检查点记录在日志文件中的地址

动态维护日志文件的方法

周期性地执行如下操作:建立检查点,保存数据库状态。
具体步骤是:
1.将当前日志缓冲区中的所有日志记录写入磁盘的日志文件上
2.在日志文件中写入一个检查点记录
3.将当前数据缓冲区的所有数据记录写入磁盘的数据库中
4.把检查点记录在日志文件中的地址写入一个重新开始文件

恢复子系统可以定期或不定期地建立检查点,保存数据库状态
定期
按照预定的一个时间间隔,如每隔一小时建立一个检查点
不定期
按照某种规则,如日志文件已写满一半建立一个检查点

使用检查点方法可以改善恢复效率
当事务T在一个检查点之前提交
Oracle中,事务T对数据库所做的修改已写入日志文件,但未必已写入数据库
Oracle写入数据库的时间是在这个检查点建立之时!
在进行恢复处理时,没有必要对事务T执行REDO操作

利用检查点的恢复策略

T1:在检查点之前提交
T2:在检查点之前开始执行,在检查点之后故障点之前提交
T3:在检查点之前开始执行,在故障点时还未完成
T4:在检查点之后开始执行,在故障点之前提交
T5:在检查点之后开始执行,在故障点时还未完成
恢复策略:
T3和T5在故障发生时还未完成,所以予以撤销
T2和T4在检查点之后才提交,它们对数据库所做的修改在故障发生时可能还在缓冲区中,尚未写入数据库,所以要REDO
T1在检查点之前已提交,所以不必执行REDO操作

<T1 start>
<T1, A, 0, 10>
<T1 commit>
<T2 start>
<T2, B, 0, 10>
<T3 start>                   
<T3, C, 0, 10>
<T3, C, 10, 20>
<checkpoint{T2,T3}>
<T4 start>
<T2 commit>
<T4, A, 10, 20>
<T5 start>
<T4, D, 0, 10>
<T4 commit>

   1.从重新开始文件中(Oracle控制文件)找到最后一个检查点记录在日志文件中的地址,由该地址在日志文件中找到最后一个检查点记录
2.由该检查点记录得到检查点建立时刻所有正在执行的事务清单ACTIVE-LIST={T2,T3}
建立两个事务队列
UNDO-LIST 
REDO-LIST 
把ACTIVE-LIST暂时放入UNDO-LIST队列={T2,T3},REDO队列暂为空。
3.从检查点开始正向扫描日志文件,直到日志文件结束
如有新开始的事务Ti,把Ti暂时放入UNDO-LIST队列={T2,T3,T4,T5}
如有提交的事务Tj,把Tj从UNDO-LIST队列移到REDO-LIST队列={T2,T4}
4.对UNDO-LIST中的每个事务{T3,T5}执行UNDO操作
    对REDO-LIST中的每个事务{T2,T4}执行REDO操作

数据库镜像

DBMS自动把整个数据库或其中的关键数据复制到另一个磁盘上
DBMS自动保证镜像数据与主数据库的一致性
每当主数据库更新时,DBMS自动把更新后的数据复制过去

没有出现故障时
可用于并发操作
一个用户对数据加排他锁修改数据,其他用户可以读镜像数据库上的数据,而不必等待该用户释放锁

频繁地复制数据自然会降低系统运行效率
在实际应用中用户往往只选择对关键数据和日志文件镜像,而不是对整个数据库进行镜像

如果数据库只包含成功事务提交的结果,就说数据库处于一致性状态!保证数据一致性是对数据库的最基本的要求。
事务是数据库的逻辑工作单位
DBMS保证系统中一切事务的原子性、一致性、隔离性和持久性

DBMS必须对事务故障、系统故障和介质故障进行恢复
恢复中最经常使用的技术:数据库转储和登记日志文件
恢复的基本原理:利用存储在后备副本、日志文件和数据库镜像中的冗余数据来重建数据库

常用恢复技术
事务故障的恢复
UNDO
系统故障的恢复
UNDO + REDO
介质故障的恢复
重装备份并恢复到一致性状态 + REDO

提高恢复效率的技术
检查点技术
可以提高系统故障的恢复效率
可以在一定程度上提高利用动态转储备份进行介质故障恢复的效率
镜像技术
镜像技术可以改善介质故障的恢复效率

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。