日期:2014-05-16  浏览次数:20585 次

Oracle恢复内部原理

Oracle 7 v7.2 恢复大纲


作者:Andrea Borr  & Bill Bridge


版本:1                May 3, 1995


摘要


本文概述了Oracle 7.2版本如何进行数据库恢复。本文读者应当熟悉Oracle 7.2的管理指南。相比于管理指南,本文目的是为了更详细描述Oracle恢复用到的算法、数据结构以及一些技术细节。



一、简介



Oracle数据库提供了下列两类失败模式下的数据库恢复:


1.  实例失败:丢失了Oracle数据缓存中的数据或者内存中的数据


2.  介质失败:丢失了数据库文件



   上面两种模式的任一种失败情景,在恢复的时候想要保证数据库一致性,都有一些前提条件必须满足。


   虽然恢复的过程有一些共同点,但前提条件的差异使得恢复的执行也有很大差异:


1.  实例恢复:恢复Oracle数据缓存中丢失的数据

2.  介质恢复:恢复数据库文件丢失的数据


1.1  实例恢复和介质恢复的共同的机制


   实例恢复和介质恢复都依赖重做日志。重做日志由一些重做日志线程组成。单实例环境中重做日志只有一个重做线程,并行服务器环境中每个实例都有一个重做线程。


    一个重做日志线程指的的是一组存放在操作系统上的文件,文件里记录了该实例对数据库的所有变更——已提交的变更和未提交的变更(后者指还存在Oracle数据缓存区中的数据块变更)。因为实例也修改了回滚段中的块,所以回滚段的变更也记录在重做日志线程中。


 
    实例恢复和介质恢复的第一步都是前滚。前滚属于数据库恢复层面的。在前滚的过程中,重做日志中记录的数据变更被重新应用到数据文件中。因为回滚段的变更也记录在重做日志中,所以前滚过程还会重新构建回滚段块。当前滚结束时,重做日志中记录的所有变更都应用到数据文件上了。此刻,数据块不仅包含了已经提交的数据,也包含了一些未提交的数据。


    实例恢复和介质恢复的第二步就是回滚。回滚属于数据库事务层的任务。回滚过程中,回滚段中记录的由前滚导致的未提交的事务所做的修改将被撤销。


1.2  实例失败和恢复,崩溃失败和恢复


  实例失败指当实例突然终止时(如因为shutdown abort或主机掉电),实例数据缓存中的内容就都丢失了。


    崩溃失败指数据库的所有实例都同时失败。单实例环境中实例失败等同于崩溃失败。崩溃恢复指的是将所有实例都恢复到崩溃前的一致状态。这一切都是在命令alter database open 之后自动进行的,用户无法干预。


    实例失败会损害数据库的一致性因为它导致该实例的脏数据丢失。所谓“脏数据”就是指实例数据缓存中的数据块内容比数据文件上的要新。当实例崩溃时,还没有来得及将脏数据写入到数据文件中。之所以导致存在这个脏数据丢失问题是因为Oracle的缓存管理采用的是有利于事务处理性能的算法而不是有利于防止实例崩溃的。如下这些有利于性能调优的缓存管理算法使得实例恢复过程有点复杂:


1.  LRU(最近最少使用)缓存替换算法

2.  提交时不强制将脏数据刷新到数据文件中



 
  上面的算法导致实例失败时对数据库完整性的损害体现在如下几点:


A.  在实例崩溃时,数据文件中可能包含一个原子事务修改的所有块中的部分块而不是全部


B.  在实例崩溃时,数据文件中可能包含一些未提交事务修改的块


C.  在实例崩溃时,一些已提交事务修改的块可能还没有刷新到数据文件中,数据文件中包含的是该事务修改之前的数据块。


    在实例恢复过程中,数据库恢复层修复了上面的损害点A和C,然后后续的数据库事务层修复了损害点B。


除了那些用来修复数据库完整性损害的前提条件外,实例恢复还需要满足一些前提条件:


1. 实例恢复必须在联机的数据文件上进行恢复。

2. 实例恢复必须使用联机重做日志文件,不能要求使用归档重做日志文件。虽然实例恢复也可以通过使用归档重做日志文件进行恢复(数据库运行在非归档模式除外),但那种恢复过程在要求用户先还原归档日志文件的的时候是不能自动进行的。

3. 实例恢复过程的调用是自动的,隐含的在下次数据库启动的时候被调用。

4. 实例恢复过程中侦测修复的文件或修复过程本身都是自动进行的,无需人工干预。

5. 实例恢复中前滚时间的长短是由Oracle数据库内部机制(checkpoint)和用户配置的参数(如日志文件的大小和数量,checkpoint的频率,并行恢复的参数等)决定的。