知识大全 Oracle恢复内部原理

Posted 文件

篇首语:人之所以有一张嘴,而有两只耳朵,原因是听的要比说的多一倍。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Oracle恢复内部原理相关的知识,希望对你有一定的参考价值。

Oracle恢复内部原理  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

     简介

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

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

   介质失败 丢失了数据库文件

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

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

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

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

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

  实例恢复和介质恢复都依赖重做日志 重做日志由一些重做日志线程组成 单实例环境中重做日志只有一个重做线程 多实例环境中每个实例都有一个重做线程

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  综上所述 Oracle的内存管理策略适合于性能调优而不是降低实例崩溃的影响 本文描述了Oracle为解决采用这种LRU和提交不刷新数据块的算法带来的问题所用到的一些内部机制 这些机制保证了实例恢复的前提条件得到满足同时又兼顾了数据库性能 这些机制如下

   提交前先刷新日志块

  这个机制修复损害C 保证了在事务提交的时候 所有跟该事务有关的重做日志记录包括提交记录都已经写入到重做日志文件中

   检查点机制

  界定了实例恢复时必须应用的重做日志的量 这一点跟联机日志切换结合起来使用确保实例恢复的时候只需要联机重做日志和当前联机数据文件

   联机重做日志切换机制

  跟检查点机制结合起来使用确保实例恢复的时候只需要联机重做日志和当前联机数据文件 它保证当前的检查点总是超前即将被重用的联机重做日志文件

   写日志优先

  这个机制修复损害A B 因为a)在实例崩溃时刻 数据文件上的所有变更都在重做日志中找到记录 b)所有数据块在写到数据文件之前都先写入跟回滚段和数据块的重做记录

   写重做日志记录是原子的

  这个机制可以修复损害A B (注 每笔重做日志记录都是由三个部分组成 重做日志记录头 回滚段改变向量 数据库改变向量 这三部分在写入重做日志时是原子的 不可分割的!)

   线程打开标志位

  用于数据库启动时判断是否需要崩溃恢复

     介质失败和恢复

  实例失败影响逻辑上的数据库完整性 因为实例失败的时候数据文件是可以恢复到一致状态的 实例恢复以当前数据文件为起点 用联机重做日志进行恢复

  介质失败则不同 影响的是物理上的数据库完整性或可用性 因为数据文件已经损坏 介质恢复要先还原该数据文件的备份作为介质恢复的起点 用归档重做日志和联机重做日志做前滚操作 直至数据文件备份后实例崩溃前最近的一个一致状态或者数据文件备份后实例崩溃前的任意一个一致状态 介质恢复操作必须由下面命令来执行 RECOVER DATABASE RECOVER TABLESPACE RECOVER DATAFILE

  根据失败场景分析 介质失败对数据库完整性的破坏可能跟实例失败一样 如当一个块被读入到数据缓冲区中修改后正要被DBWR进程将更新后的数据块写回到数据文件中时发生I/O故障 也可能导致前面提到的A B C三点损害 此外 介质失败时不仅仅是当前脏数据永久丢失了 而且该数据文件上自上次备份后的所有更新的都丢失了

  在介质恢复之前 必须先还原被损坏的数据文件 然后在这些数据文件上应用相关的归档日志和联机重做日志前滚到介质失败前的一致状态

  介质恢复和实例恢复上面提到A B C三种损害有一些共同的前提条件 然而介质恢复和实例恢复的前提条件还是有如下五点不同

   介质恢复前必须先还原受损坏的数据文件

   介质恢复除了要求联机重做日志外还要有归档重做日志

   介质恢复必须显示调用 需要人工干预

   介质失败不能自动被侦测到 只有在某个数据文件或数据库备份被还原的时候才能自动侦测到需要介质恢复

   介质恢复所用的前滚时间长短是由用户备份策略决定的(如备份的频率 并行恢复参数等) 而不是有Oracle内部机制决定

     基础数据结构

     Controlfile

  控制文件包含了数据库中所有其他文件的状态信息

  控制文件包含了如下几类数据

  A 数据库信息记录(一条)

  B 数据文件记录(每个数据文件一条)

  C 线程记录(每个线程一条 注 每个实例一个线程)

  D 日志文件记录(每个日志文件一条)

  E 文件名记录(每个数据文件或者日志文件成员一条)

  F 日志历史记录(每个已经完成的日志文件一条)

  控制文件的被后面文档引用到的字段如下 后面是引用该字段的章节

     数据库信息记录(控制文件)

  所含字段

  A.resetlogs timestamp:

  B.resetlogs scn:

  C.enabled thread bitvec:

  D.force archiving scn:

  E.database checkpoint thread(thread record index) :

     数据文件记录(控制文件)

  A.thread checkpoint structure:

  B.thread open flag:

  C.current log (logfile record index)

  D.head and tail (logfile record indices) of list of logfiles in thread:

     日志文件记录(控制文件)

  A.log sequence number:

  B.thread number:

  C.next and previous (logfile record indices) of list of logfiles in thread:

  D.count of files in group:

  E.low SCN:

  F.next SCN:

  G.head and tail (filename record indices) of list of filenames in group:

  H. being cleared flag:

  I. archiving not needed flag:

     文件名记录(控制文件)

  A.filename

  B.filetype

  C.next and previous (filename record indices) of list of filenames in group:

     日志文件历史记录(控制文件)

  A.thread number:

  B.log sequence number:

  C.low SCN:

  D.low SCN timestamp:

  E.next SCN:

     数据文件头

  数据文件头部分的被后面文档引用的字段如下 后面跟的是引用该字段的章节:

  A.datafile checkpoint structure:

  B.backup checkpoint structure:

  C.checkpoint counter:

  D.esetlogs timestamp:

  E.resetlogs SCN:

  F.creation SCN:

  G.online fuzzy bit:

  H.hotbackup fuzzy bit:

  I.media recovery fuzzy bit:

     日志文件头

  日志文件头部分的被后面文档引用的字段如下 后面跟的是引用该字段的章节:

  A.thread number:

  B.sequence number:

  C.low SCN:

  D.next SCN:

  E.end of thread flag:

  F.resetlogs timestamp:

  G.resetlogs SCN:

     改变向量(Change Vector)

  改变向量表示对数据块的一次变更 改变向量头部记录了发生变更的数据块的DBA地址 该块的版本号 序列值和操作代码 头部以后的内容跟具体的变更操作有关 数据块版本号和序列值是在创建改变向量时从数据块的头部复制过来的 当块被更新后 版本号值就比原来的值大一点 而序列号则被设为 此后数据块每变更一次 序列值就增长

     重做记录

  一个重做记录是由一组改变向量组成 代表一个数据库变更 如一个事物的重做记录由三部分组成 首先是事务表(回滚段段首)的改变向量 再次是回滚块的改变向量 最后是数据块的改变向量 一个事物可以产生多个重做记录组成 一个重做记录是数据库恢复的最小单位 一个重做记录由多个改变向量组成的机制允许多个数据块被修改并且这些修改要么都发生要么就都没发生 即使发生突然的失败 这种原子性是由数据库缓冲层的一个基础Job来保证的 Oracle恢复保证重做记录是不可分割的 即使在数据库失败的时候

     System Change Number (SCN)

  SCN描述了数据库的一次事物提交版本 一次查询也是查询数据库的某个SCN产生时刻时的内容 SCN会被分配和保存在事务的重做记录的头部 SCN也会保存在控制文件和数据文件中 SCN是由 位长的数字组成

     重做日志

  所有数据块的变更发生时都是先构建一个重做记录 然后把这个重做记录保存到重做日志中 最后在数据块中应用该变更 恢复的过程就是在老的数据块上应用重做日志是该数据块变成当前的数据块 这个过程在当前版本数据丢失的情况下是必须的

  当一个重做日志文件写满了时 就会发生日志切换 每个日志是由一个线程号标识 序列号(一个线程以内再分)和该日志跨越的SCN范围 这些信息保存在日志文件头中

  重做日志文件中的重做记录是根据SCN排序的 此外 重做记录中包含的具体数据块的改变向量也是按SCN递增顺序发生的 即使是跨多个线程(这种情况发生在多个实例环境中) 只有某些重做记录头部包含有SCN信息 但是所有的记录都是在某个SCN被分配后才发生的 日志文件的头部包含了最小的SCN和下一个SCN 最小的SCN是这个日志文件中第一个重做记录对应的SCN 下一个SCN是当前日志序列递增后的下一个日志文件的的最小SCN 当前在使用的重做日志的下一个SCN都是无限大 因为还没有日志文件的序列号比当前日志的序列要大

     重做线程

  每个实例产生的重做日志被称为一个重做日志线程 一个日志线程由联机重做日志和归档重做日志(前提是数据库运行在归档模式下) 联机重做日志是由两个或更多个日志组组成 每个日志组由一个或更多重复的日志成员组成 通常说一个日志组 重做日志 联机日志或简称日志都是指一个日志组的成员集合(可能是一个或者多个) 一个重做日志只包含该日志所属的线程记录的日志 各个线程在写日志时分配日志文件的序列号是彼此独立的 各个线程的日志组之间的日志切换也是独立进行的

  每个日志文件组在控制文件中都有一笔记录描述它的信息 每笔记录通过日志号码查找 注意日志号跟日志组的号码是一致的 而且是全局唯一的(多实例环境中) 每个重做线程的日志文件组列表记录都在每个重做线程记录的后面(类似于一种Head Detail结构) 各个日志文件组的记录中都分别有一个向前和向后的字段记录上一个日志文件组和下一个日志文件组(通过日志文件组号来记录) 日志文件组的成员信息在日志文件组的记录中描述

     Redo Byte Address (RBA)

  RBA指定了重做日志的位置 长度为 字节 由三部分组成 日志序号 块号以及块中的字节序号

     检查点结构

  检查点结构定义了数据库重做日志的一个点 检查点结构信息保存数据文件头部和控制文件中每个重做线程的记录中 这些检查点结构用于恢复时告诉数据库从哪个重做日志的哪一笔重做记录开始恢复

  检查点结构的关键字段是检查点SCN和当前激活的线程标志

  检查点SCN能有效的定位每个激活中重做日志的任一位置(激活的定义见 ) 对于每个重做线程 检查点SCN就是发生一次提交时的时间点以及对应重做日志的位置 根据重做日志文件头部的重做记录可以发现第一笔重做记录产生时分配的SCN是检查点SCN或更高一点

  当前激活的线程标志标记了这个检查点SCN被分配时哪个重做线程处于激活状态 注意每个线程在激活时都有一个状态位被设置 不管它是打开还是关闭状态 每个激活的线程都有一个重做日志 重做日志包含该检查点SCN 这点证明了该重做日志存在(联机或者已经归档)

  检查点结构还还保存了这个检查点SCN被分配时的时间戳 这个时间戳只是输出一些信息便于用户查找日志

  此外 检查点结构还保存了检查点SCN被分配时的线程的数量和线程中当前RBA地址 显示的存储线程的RBA地址(相对于存储SCN作为线程的隐式的指针)使得在单实例环境中日志序列和归档日志名称更容易找到

  检查点在一段时间内可以支持高达 个重做日志线程 总计 字节长

     日志历史

     线程检查点

  每个激活的线程在控制文件中的记录中都包含了一个检查点结构 我们称之为线程检查点 这个检查点中的SCN字段就是线程检查点SCN 还有线程序号和RBA字段指明了这个线程检查点跟哪个SCN相关

  线程检查点结构在实例每次对其线程发出检查点操作时被更新(见 ) 检查点发生时 跟该实例相关的线程会把重做日志里记录的小于该线程检查点SCN的重做记录保护的脏数据写入到联机数据文件中

  线程检查点事件保证了该线程的重做日志中所有小于该线程检查点SCN的重做记录对应的脏数据都被写入到磁盘(注意到如果该线程关闭了 重做日志里就没有SCN比线程检查点SCN还小的记录 )

  实例恢复的时候要保证对应线程的所有重做日志都应用到数据文件中 因为线程检查点SCN以前的重做日志已经被应用了 所以实例恢复可以保证 在启动重做日志进程时只要从线程检查点SCN开始应用 直至重做日志文件的尾部 所有线程的重做日志都被应用

     数据库检查点结构

  数据库检查点结构就是所有打开的线程中线程检查点SCN最小的那个线程检查点 数据库检查点线程的序号 当前线程检查点是数据库检查点的那个线程的序号 被记录在控制文件的数据库信息部分

  因为每个实例都保证对应线程检查点SCN以前的重做日志保护的脏数据已经写到数据文件中 并且数据库检查点SCN是所有线程中线程检查点SCN最小的 所以可以说所有实例中在数据库检查点SCN以前的重做日志记录所保护的脏数据都被写到数据文件中 换句话说是数据库所有联机数据文件都在数据库检查点时发生了检查点操作 这就是一个实例检查点了对应线程时用数据库检查点更新了所有联机数据文件检查点(见下面)的基本原理(见 )

     数据文件检查点结构

  数据文件检查点结构指的是每个数据文件的头部包含的检查点结构 其中的SCN字段就是数据文件检查点SCN

  由前面而知 针对每个数据文件 在其检查点SCN以前的所有线程的重做日志保护的脏数据都已经被写入到数据文件 每个联机的数据文件会把它的检查点SCN记录在控制文件中 但这个值可能跟数据文件头部的检查点SCN不一致 Oracle恢复层设计成能接受这种不一致 当实例失败发生在更新数据文件头部的检查点之后提交控制文件 事务 之前时 二者没有及时同步造成不一致 (注 控制文件 事务 是数据库内部机制 独立于Oracle事务层 指的是保证对控制文件任意大的更新都能够自动被 提交 )

  数据文件检查点执行时(见 ) 数据文件头部的检查点结构会被更新 并且保证所有线程产生的重做日志记录在该检查点SCN以前对应的脏数据都已经被写入到磁盘上了

  线程检查点事件(见 )保证了所有线程产生的所有SCN在检查点SCN以前的重做日志记录对应的脏数据都被写入到磁盘了 线程检查点事件可能会推进数据库检查点(如在单实例环境中 或该线程的检查点最旧了)如果数据库检查点推进了 新的检查点将更新所有联机数据文件的检查点结构(热备份中的数据文件除外 见第 节)

  介质恢复时要保证对即将恢复的数据文件把任一个线程产生的重做日志记录都要应用上去 由前面知对即将恢复的数据文件来说 每个线程产生的重做日志在该数据文件检查点SCN以前的重做日志都已经得到应用 介质恢复在重新应用日志时只需要从数据文件检查点SCN开始支持恢复结束点 注 用户指定结束的SCN或时间点等(不完全回复) 又或者是所有线程的结束点(完全恢复)

  因为数据文件检查点保存在数据文件的头部中 所以在数据文件的备份中同样也存在 如果是热备份产生的备份 热备份保证了当数据文件处于热备份状态时 即使在复制要备份的数据文件过程中数据库要更新该数据文件上的脏数据 数据文件中所有数据库的版本跟数据文件头部的检查点结构的版本是一致的 都是在热备份开始那一刻时的版本

     结束SCN

  每个数据文件在控制文件的记录中都有一个字段叫结束SCN 如果该数据文件是脱机状态或只读的 该结束SCN的值表示对该数据文件不会有再比这个结束SCN更大的重做记录 如果该数据文件是联机的并且有一个实例打开了数据库 结束SCN就会被设置为无限大(注 值为 xffff ffffffff) 结束SCN用于介质恢复时告诉重做程序在该数据文件上应用重做日志时到了这个SCN时就停止 这保证了在数据库打开的状态下恢复一个脱机的数据文件时介质恢复能停下来

  不管数据文件脱机或者只读 结束SCN都会被设置为具体的SCN 不管脱机操作时 立即 (因为I/O错误导致或者因为数据文件所在表空间被立即脱机)还是 临时的 或 正常的 (数据文件所在表空间正常脱机) 不过在数据文件被立即脱机时 不会发生数据文件检查点(见 ) 并且对应的脏数据都丢失了 因此在将该脱机文件变成联机时介质恢复需要重新应用重做日志直至结束SCN 介质恢复不需要应用结束SCN以后的重做日志 因为就不存在这样的重做日志 如果结束SCN等于数据文件检查点SCN 那么该数据文件就不需要恢复

     检查点计数

  在数据文件头部和数据文件在控制文件的记录部分都有一个检查点技术 检查点计数是用来判断数据文件或者控制文件是否是过时的(从一个备份中恢复出来的)

  每次发生线程检查点事件时 检查点计数都会递增 从而即使数据文件的检查点没有被推进时检查点计数也会增加 线程检查点事件时数据文件检查点没有被推进的原因可能是数据文件处于热备份状态 或者它的SCN比要更新的检查点SCN值还要新(如数据文件时新增的或者刚经历了一次数据文件检查点事件)

     表空间干净结束SCN

  数据字典TS$有两列表示 表空间干净结束SCN(注 i中是SCNWRP和SCNBAS组合表示) 它表示表空间是在这个SCN时被脱机或者设置为只读 如在对数据文件发出检查点操作后(见 ) 数据文件检查点SCN被记录到TS$中作为表空间干净结束SCN 这样的表空间在数据库以重置日志方式打开后不需要被删除(见 ) 在介质恢复时 以重置日志方式打开日之前 这种表空间会处于脱机状态 重置日志后 表空间也不需要恢复 允许被直接设置为联机状态或读写状态 重置日志后建议立即备份表空间

  当把一个脱机且干净的表空间置为联机或者可读写时 表空间干净结束SCN会被设置为 (中间可能短暂性被设置为无穷大) 立即或临时性的将表空间置为脱机状态 tablespace clen stop SCN也会是

  一个在TS$中表空间干净结束SCN为非零的表空间被认为在那个SCN时是干净的 指的是该表空间包含了直至那个SCN的所有的重做记录保护的数据 没有大于那个SCN的重做日志记录存在 如果该表空间的所有数据文件都是脱机时刻的状态或者只读的 那在将表空间置为联机状态时是不需要恢复的 注意到表空间干净结束SCN同数据文件在控制文件中的记录的结束SCN是有区别的 结束SCN只是表明该数据文件没有超过结束SCN的重做日志记录 但并没有暗示该数据文件已经包含了结束SCN以前的所有重做日志记录所保护的脏数据

  表空间干净结束SCN存放在TS$中而不是控制文件中 所以可以得到重做日志的保护并且处于正确的状态 如在一个不完全恢复后(见 ) 该表空间的状态依然正确 它的值也不会随着使用了备份的控制文件 更重要的是这种SCN的存在使得该表空间在以重置日志方式打开数据库后依然可以存在 因此不完全恢复期间的脱机了的表空间可以在以重置日志方式打开数据库后直接置为联机状态或设置为可读写 如果没有表空间干净结束SCN 就没有办法知道该表空间不需要被重置日志抛弃的重做日志记录 那时唯一可选的办法就是将该表空间脱机

     数据文件脱机范围

  数据文件在控制文件中记录了脱机时的SCN和脱机结束时的检查点 二者界定了该数据文件不需要重做日志的范围 因此介质恢复的时候可以直接跳过该范围的重做日志 这个特性帮助恢复了一个已经脱机了或者设为只读了很长一段时间的数据文件变成联机或可读写

  当一个数据文件从脱机状态变为联机状态时(或从只读变成可读写时) 脱机范围设置规则如下 脱机起始SCN取的是该表空间的表空间干净结束SCN 脱机结束检查点取的是数据文件设置为联机(或可读写)时的数据文件检查点

     重做日志

  重做日志描述了对数据块的所有变更 这一节主要描述数据库打开的时候写日志时的一些操作

     原子修改

  数据库最基础的操作就是以原子的方式修改数据块 前台进程想修改一个或几个数据块时 首先得获取对数据缓冲区中包含该块的缓存的一个排它访问权限 然后构建改变向量 重做日志缓冲区中分配空间保存重做记录 重做缓冲区位于SGA中 LGWR进程定时将重做日志缓冲区中的重做记录写入到重做日志文件中以释放空间 当重做日志满了的时候 LGWR就要做日志切换 注意在重做日志缓冲区中分配空间的同时也会在重做日志文件中分配空间 重做日志缓冲区空间分配后前台进程负责构建重做记录 此后才能修改数据缓冲区中的数据块 然后当重做日志缓冲区中的重做记录写到重做文件中才算数据库变更完成 恢复保证重做日志中记录的变更都会应用到数据文件中(除非是不完全恢复)

     写日志优先

  写日志优先是一个缓冲区执行协议 用来协调写脏数据到数据文件中和写重做日志记录到重做日志文件的顺序 根据写日志优先协议 在DBWR进程将脏数据写入到数据文件中之前 LGWR进程必须先将对应的重做日志记录写入到重做日志文件中

  注意 写日志优先协议跟提交时写日志协议是独立的(见 )

  同时注意 写日志优先协议只适用于将那些在数据缓冲区中的脏数据写入到数据文件这种情形 不适用于直接路径写(如由直接路径读导致的)

  写日志优先协议保证了数据文件中没有一种变更在重做日志文件中没有记录 不惜以失败为代价

  写日志优先协议还保证了所有数据块都在先写完重做日志并保证能够回滚的情况下才写到磁盘的 使得如果提交失败的时候可以回滚所有修改 这里的重做信息其实就是回滚段的重做信息

  写优先协议在数据库事务层保证事务的原子性起了很大作用

     事务提交

  事务提交时会分配一个SCN并且建立一个包含那个SCN提交的重做日志记录 当事务所有的重做记录(包括mit对应的重做记录)都写到磁盘上的重做日志文件中时 mit过程才算结束 因此mit会强制日志刷新到磁盘上 至少截止到mit的重做记录 这就是通常说的log force at mit

  恢复就是设计成这样 在事务mit的时候只需刷新重做记录到重做日志 而不用刷新该事务修改的所有脏数据 为的是在即使失败的情况下也能保证事务持久性 这就是通常说的no datablock force at mit

     线程检查点事件

  线程检查点事件发生时 会将该线程的重做记录中SCN小于指定值的重做记录保护的脏数据都刷新到数据文件中 完成后 该线程在控制文件中的线程检查点结构会被更新

  线程检查点事件开始时 首先是得到一个SCN 初始化一个检查点结构 然后该实例的数据缓冲区中所有脏数据都被打上做检查点的标识 DBWR分阶段将这些标识的脏数据写入到数据文件中 当所有脏数据都写入到数据文件中时 检查点结构中的SCN被更新为前面得到的SCN 然后用该检查点更新该线程在控制文件中的检查点记录

  一个线程检查点事件可能会或者不会推进数据库检查点 当只有一个打开的线程时 新的线程检查点也同时是新的数据库检查点 如果有多个打开的线程 并且当前线程就是数据库检查点所联机程 当前线程的检查点事件会推进数据库检查点 因为新的检查点SCN是最近分配的 很有可能比其他打开状态的线程的检查点SCN要大 数据库检查点SCN将推进到新的最小的线程检查点SCN 不过如果当前线程原有检查点不是数据库检查点 那么该线程的检查点事件不会推进数据库检查点

  数据库检查点推进时 每个数据文件头部的检查点计数也会增长 并且 每个数据文件只要不是在热备份中或者没有更高的检查点SCN(如新增的数据文件或者刚恢复的数据文件) 数据文件头部的检查点都会推进到跟新的数据库检查点一致 数据文件头将写入磁盘 同时 数据文件在控制文件中的记录的检查点SCN也会更新为新的数据库检查点SCN

     联机模糊位

  你或许已经注意到 在数据缓冲区中还存在一些比那些标识了检查点的脏数据还要新的修改 它们是联机程检查点事件后产生的 因此产生时的SCN要高于数据文件头部的线程检查点SCN 这些脏数据可能因为很多原因也被写到数据文件中 这时 我们称这个数据文件是 联机模糊的 就是说它包含了一些检查点SCN以后的变更 一个联机的数据文件在数据库打开的时候常常是联机模糊的

  联机模糊状态是通过设置数据文件头部的一个联机模糊位来标识的 所有数据文件的联机模糊位是在数据库打开的时候设置的 另外 一个脱机的数据文件在解除脱机状态时也会设置它的联机模糊位

  联机模糊位在最后一个实例正常关闭或者立即关闭的时候被清除 其他清除该状态位的场景有 (i)崩溃恢复结束 (ii)当介质恢复进程到了崩溃恢复结束时做检查点(刷新所有脏数据)(见 ) (iii)当将数据文件临时或正常脱机时(如在检查点之前将文件脱机) (iv)当发出开始热备份指令(见 )

  在 节我们将见到如果有数据文件是联机模糊的 那么以重置日志方式打开数据库将会失败

     数据文件检查点事件

  数据文件检查点事件发生时 所有实例(所有打开的线程)都将强制刷新指定SCN之前的所有重做记录保护的脏数据 完成后 数据文件头部的检查点将被更新别写到磁盘上

  数据文件检查点事件发生在如开始热备份(见第 节)和将表空间的部分数据文件正常脱机时

     日志切换

  当实例需要产生一些重做记录而重做日志中却没有充足的空间时 就会发生日志切换 首先是找到一个联机的重做日志文件候选

  候选日志条件一是该重做日志文件的状态不是激活的 即它不能是崩溃或实例恢复还需要的重做日志文件 换句话说 覆蓋它不能造成实例恢复需要的重做记录丢失 强制执行的原则是联机重做日志不能被重用 除非该线程检查点已经超出该重做日志最后一笔重做记录对应的检查点 因为实例恢复时是从当前检查点SCN开始 根据RBA再查找联机重做日志 而日志切换的候选日志是实例恢复不需要的 则说明当前检查点SCN应该超出候选日志的最高SCN 如果不是这样 说明候选日志上正在进行检查点操作(还没有做完) 此时不能切换到日志上

  候选日志条件二是它已经完成归档了 当然前提是数据库必须运行在归档模式下 如果没有 则通知归档进程进行归档 归档未完成之前 此时也不能切换到该日志上

  当日志切换完成时 在新的日志上会有个线程检查点操作 期望在检查点操作能在下一次日志切换来临前完成

     归档中的日志切换

  在并行服务器环境中 由于每个线程都独立切换日志 各个线程中的日志的起始SCN值并不一样 但是对于启用状态的线程的归档日志的SCN范围要求大致相同 这保证每个线程的最后一笔归档日志都是当前日志 如果一个启用状态的线程的日志未归档 且含有一个比较老的SCN(当该线程的实例活动很少时常发生) 它将不能用主库的归档日志来把备库站点恢复到一个更高的SCN 尤其是该日志没有包含重做日志时

  解决这个问题的方法就是当其他线程的当前的日志明显比当前线程的归档日志还要落后时就强制其他线程做日志切换 如果其他线程是打开的 则有一个锁专门促使缓慢的实例去切换日志并归档 如果其他线程是关闭的 则当前活动的线程代替它做日志切换并进行归档 你会注意到这会导致一种现象就是一个线程处于启用状态但却从未使用却有一堆只有文件头的归档日志 该强制归档时的SCN会维护在控制文件中 Oracle会努力去对所有小于或等于该SCN的联机日志进行归档 通常SCN最小的日志会首先被归档

  命令ALTER SYSTEM ARCHIVE LOG CURRENT 用于手动对所有启用状态的线程的当前日志进行归档 它强制所有启用的线程 无论打开还是关闭的 切换新日志 然后归档所有旧的日志 直至发出命令前所有的重做日志都被归档才返回 这个命令保证了热备份恢复时所需要的所有日志都得到归档 它还保证了主库及时往备库传送归档日志以防止灾难

     线程打开

  实例打开数据库的时候 会打开一个线程用于产生重做日志 这个线程在数据库被挂载选定的 实例初始化文件中有一个参数可以指定实例打开的线程号 如果未指定实例就从公共的线程中选择一个 线程上有个锁用于防止两个实例打开同一个线程 实例打开线程的时候会在控制文件中设置线程打开标志位 每个活动的实例都持有一组线程打开锁(分别为LGWR DBWR LCK LCK 等持有) 实例关闭的时候会释放这些锁 用于实例检测并行服务器环境中其他实例是否活动 见 ) 同时实例打开线程的时候的检查点将作为线程检查点 如果是数据库首次打开 则该检查点也是数据库检查点 同时推进所有联机数据文件的检查点 注意线程打开的时候也可能会发生一次日志切换

     线程关闭

  实例关闭数据库的时候或者一个线程被实例/崩溃恢复 线程都会关闭 线程关闭的第一步就是保证不在产生重做 然后将该线程产生的日志保护的所有脏数据都刷新到磁盘上

  数据库正常关闭的时候 这个是由线程检查点事件完成 最后一次检查点时的SCN就是线程关闭时的SCN 最后线程在控制文件中的线程打开标志位被清除

  如果线程是被实例恢复结束而关闭 重做程序将从该线程最近一次线程检查点记录开始对数据文件应用该线程对应的重做日志 直至日志的结束 一旦该线程重做日志保护的所有脏数据都刷新到数据文件后 线程检查点推进到线程结束时的检查点 正常的线程检查点可能会推进数据库检查点 如果这是最后一个关闭的线程 数据库在控制文件中记录的检查点线程值将设置为该线程 即使线程已经关闭

     线程启用

  要打开一个线程 首先得启用该线程 这保证在介质恢复的时候能够找到该线程的重做日志 线程可以以公共或私有的方式启用 一个私有的线程只能被在初始化文件中系统参数指定的实例打开 这跟回滚段的使用有点类似 一个线程启用后必须至少有两组重做日志组 其中一个重做日志组是当前正在使用的 它的下一个SCN记录是无限大 以保证新的SCN永远落在当前日志的SCN范DATABASE ENABLE THREAD) 该线程启用记录用于介质恢复应用新的线程的重做记录 也就是说介质恢复打开了另外一个线程 数据库创建的时候会自动启用一个线程 从而避免了 先有鸡还是先有蛋 的争论 这也是说如果一个数据库不是运行在并行服务器环境下就不需要再启用新的线程

     线程禁用

  如果线程长时间不用 就禁用它 这也就是说介质恢复不需要该线程的重做日志记录 当一个线程被禁用的时候 它的重做日志文件可能会被删除 线程禁用之前必须先关闭它 这保证所有脏数据都刷新到磁盘上 新的SCN会作为该重做日志的下一个SCN 日志文件头也会记录该SCN同时表明这个线程已经被禁用了 这个新分配的SCN很重要 它保证了该线程任一个检查点中的SCN在该线程的一个重做日志中 也意味着禁用一个线程的时候必须打开另外一个线程 不能禁用所有线程

     热备份

  热备份指在数据文件正在使用的时候对其进行复制 复制的过程中 DBWR也在进行 因此备份可能得到一些 不一致 的备份

  a 一些数据块可能比其他块的时间要早

  b 一些数据块的SCN可能比数据文件头部的SCN还要早

  c 一些块可能包含了一个重做记录的部分更新 其他的部分可能在这个数据文件上或者其他数据文件上

  d 一些数据块可能会被损坏 因为块的头部和尾部是在不同的时间复制的

  上面的这种复制方式得到的备份集在还原后和介质恢复的时候是没有用的 介质恢复时会从数据文件上的开始热备SCN(见 中第二步)直至恢复过程结束(完整或不完整的恢复) 这样数据文件从事务上讲是一致的

  热备份一共有三个步骤

  a 执行命令 ALTER TABLESPACE BEGIN BACKUP

  b 调用操作系统的复制工具复制该表空间下所有数据文件

  c 执行命令 ALTER TABLESPACE END BACKUP

     BEGIN BACKUP

  BEGIN BACKUP命令实际对表空间的所有数据文件进行 下列操作(不需要按顺序)

   在每个数据文件头部设置了热备份模糊标志位 表明该数据文件处于热备份状态 带有这种标记的数据文件头表明这个备份是热备份 标志的目的是冻结这个数据文件头部的检查点(停留在begin backup命令发出那一刻的SCN) 这个值作用在于当备份被还原时 介质恢复能从足够早的SCN开始重新应用重做日志 因为我们不能保证数据文件头首先被复制 因此热备份期间要将数据文件头的检查点冻结支持热备份结束 这个标准也冻结了数据文件的检查点(以及在控制文件中的记录的检查点) 以免被线程检查点更新 版本后数据文件头新增了一个备份检查点以接收原本属于被冻结的检查点该接收的更新

   做了一个数据文件检查点操作 捕获了开始热备时候的检查点信息 包括开始热备的SCN 当数据文件被检查点时 所有实例都要刷新跟该数据文件有关的脏数据 如果此时需要实例恢复 检查点将等待恢复完成再继续 在开始备份的时候对数据文件进行检查点操作保证了在热备份期间 只有在发出热备份命令之后的时间里修改的块可能会被写到数据文件上

   [跟平台有关 可选] 热备份后开始数据块的前镜像记录 记录过程中 所有实例将每个要修改块的完整的块而不是修改向量记录到重做日志中 这是为了防止恢复中遇到零碎的块(不一致的块) 这多发生在数据块的大小比操作系统的块要大的时候 更新数据块导致前一部分和后一部分分别在不同的时间被复制 在热备份后恢复进程可以利用重做日志中的记录的完整前镜像构建数据块

   设置数据文件头部的检查点跟开始热备份时刻的检查点一致 并冻结它直至发出 END BACKUP 命令

   清除了数据文件的联机模糊位标志 在热备份期间该状态位一直是被清除的 直至发出 END BACKUP 命令

     复制文件

  复制是由操作系统的工具来完成 管理员必须保证复制操作发生在 BENGIN BACKUP 和 END BACKUP 之间或者文件没有使用的时候

     END BACKUP

  当发出END BACKUP命令时 各热备的表空间的数据文件将发生下列操作

   还原了数据文件的联机模糊标志位

   在重做日志中写入一笔该数据文件结束热备份的重做记录 这笔重做记录只会在介质恢复中有用 记录了热备份开始时刻的SCN(该SCN跟数据文件头部被冻结的检查点的SCN一致) 这笔记录也标志着热备份期间的重做日志的结束 介质恢复时读到这个热备份结束标记 就知道热备份期间产生的重做日志都被应用到了数据文件上 然后介质恢复就清除热备份模糊标志位 这个标志位能防止不完全恢复错误的选择在BEGIN BACKUP和END BACKUP时间点之间停止 如果一个不完全恢复在这样的点停止了 可能会导致数据文件不一致 因为备份时的复制过程可能已经包含了这个时间点之后的变更 在 将会见到 当数据文件的热备份标志位还在时 以重置日志的方式打开数据库将会失败

   清除热备份模糊标志位

   停止数据块前镜像记录

   推进数据文件的检查点到当前数据库检查点 这弥补了热备份期间线程检查点推进了数据库检查点却无法推进数据文件头检查点(因为被冻结了)

     崩溃 的热备份

  当有数据文件处于热备份状态时 正常关闭启动了热备份的实例或者最后一个实例都不被允许 还有将热备的数据文件正常脱机或临时脱机也不行 这是为了保证结束热备份的标志记录能正常产生 也告诉了管理员他们忘了发出 END BACKUP 命令

  当热备份期间实例崩溃了或者以abort方式关闭时 所有热备份中文件的热备份模糊标志位还处于被设置状态 文件头检查点还处于被冻结状态 仍旧是热备份开始时刻的检查点 即使数据文件的数据块跟数据检查点一致 文件头看起来像刚还原的备份需要介质恢复 且跟开始热备份的检查点一致 崩溃恢复还是会失败 报需要介质恢复 因为它发现数据文件处于热备份崩溃的状态中 而这个文件起始不需要介质恢复 但是需要修正一下文件头部取消 崩溃 热备份状态

  介质恢复可以恢复和打开有数据文件处于 崩溃 热备份状态的数据库 版有个更好的选择 就是用命令ALTER DATABASE DATAFILE END BACKUP将数据文件结束热备份状态 数据文件可以从视图V$BACKUP中查看 见 ) 之所以能这样做 紧接着这个命令后 崩溃恢复就可以打开数据库 注意ALTER TABLESPACE END BACKUP命令在数据库没有打开的时候是不能用的 因为数据库只有在打开的时候才能通过数据字典找到表空间对应的数据文件

     实例恢复

  实例恢复用于恢复崩溃失败或者并行服务器环境中的实例失败 所以实例恢复既可以指崩溃恢复也可以指并行服务器环境中的实例恢复(只要有一个存活的实例就可以恢复其他一个或多个失败的实例)

  实例恢复的目标就是还原失败实例在数据缓冲区中的数据块并关闭还开着的线程 实例恢复只用联机归档日志和当前联机数据文件(不需要还原历史备份) 实例恢复一次只能恢复一个线程 它从该线程最近的线程检查点开始恢复直至线程的结束

     检测是否需要实例恢复

  当Oracle内核发现一个实例死掉而对应线程在控制文件中的线程打开状态位还是开的时候会自动进行实例恢复 实例恢复在下面两种情形下自动进行

   崩溃失败后第一次打开数据库

   并行服务器个别实例(不是所有的)失败了

  在并行服务器环境中 存活的实例通过下列方法检测到一个或多个实例失败需要进行实例恢复

   存活实例的一个前台进程在将数据文件中的块读入数据缓冲区时检测到 Invalid block lock 这个多发生在另一个实例已经将该块读入数据缓冲区并用锁保护了该块 脏数据 然后该实例失败了

   存活实例的前台进程通知它的SMON进程查看失败的实例

   存活实例可以申请死亡实例的线程打开标志锁从而发现该实例已经死亡

  存活实例的SMON进程得到一个死亡实例的列表和错误的数据块列表 注 当实例恢复结束后 这些列表中的锁都会被清掉

     Thread at a Time Redo Application

  实例恢复同一时间只能处理一个线程 因此同一时间也只能恢复一个实例 在处理下一个线程之前 实例恢复会将每个线程的所有重做日志(从该线程的线程检查点开始到线程结束)应用到数据文件上 这个算法的正确性取决于同一时刻只有一个实例能修改数据缓冲中的块 在不同的实例修改同一块之间 该块会被写回磁盘 因此 实例恢复时从磁盘中读入数据缓存中块只需要某一个线程就够了 那个线程包含了该块最新的修改日志

  实例恢复总是能够只要该线程的联机日志就可以完成 崩溃恢复首先处理线程检查点最低的那个线程 按照线程检查点SCN递增的顺序进行恢复 保证了数据库检查点是由每个恢复过的线程推进的

     当前联机数据文件

  检查点计数器用于校验数据文件是当前联机数据文件而不是历史备份 如果数据文件是从备份中还原出来的 则需要首先进行介质恢复

  当数据文件是从备份中还原出来的时候 即使只要联机重做日志就可以恢复 介质恢复仍然不可避免 理由是崩溃恢复在处理每个线程的时候都是应用该线程检查点以后的重做日志 崩溃恢复能够用这种重做算法是因为每个块只需要最多一个线程的重做日志

  然而 如果在还原的备份上进行恢复时 无法断定要哪些线程的重做日志 因此一次一个线程的算法在这种情况下不起作用 在备份上恢复需要将多个线程的重做合并 如把数据文件检查点后的所有重做日志 按照SCN递增的顺序合并各个线程中的重做日志 这种线程合并重做算法只有介质恢复才会用(见第 节)

  崩溃恢复如果使用线程合并重做算法恢复一个备份 即使数据文件的检查点跟数据库检查点一致 依然会失败 原因是在所有的线程中 崩溃恢复会丢失数据库检查点和最高的检查点之间的重做日志 相比之下 介质恢复会从数据文件检查点开始应用重做程序 而且 即使崩溃恢复也从数据文件检查点开始应用重做程序 还是会失败 因为它只会去找联机重做日志 而所有线程可能都已经将其重做日志归档了并重用了联机日志

  如果使用了命令STARTUP RECOVER 崩溃恢复会因为数据文件需要介质恢复而失败 此时在数据库打开之前会自动调用RECOVER DATABASE进行介质恢复

     检查点

  实例恢复不会尝试应用数据文件检查点之前的重做日志(数据文件头部的检查点SCN不能决定是否需要实例恢复)

  实例恢复读取从数据文件检查点之后到线程结束之际的重做日志 找到该线程分配的最大的SCN 用于关闭线程和推进线程检查点 实例恢复结束后也会推进数据文件检查点和检查点计数器

     崩溃恢复完成

  崩溃恢复完成时 所有数据文件的联机模糊位 热备份模糊位 介质恢复模糊位都将被清除掉 然后在重做日志中写入一笔特殊的重做记录 标记崩溃恢复的结束 这条记录用于通知介质恢复在恢复时何时可以清除数据文件的联机模糊位和热备份模糊位

     介质恢复

  介质恢复用在丢失或损坏数据文件或者丢失了控制文件的情形 介质恢复将还原的数据文件恢复成当前数据文件 还能够恢复数据文件异常脱机时没有来得及做检查点操作丢失的变更 介质恢复使用归档日志和联机日志 跟实例恢复不同的是 介质恢复必须由命令显式调用

     什么时候做介质恢复

  由 节知道 数据文件如果是还原的备份 在打开前都要进行介质恢复 即使是应用联机日志就可以恢复的 另外一种情形就是数据文件异常脱机没有做检查点操作 不做介质恢复数据库是无法打开的 需要介质恢复的数据文件也不能联机 数据库没有被任何实例打开的时候 介质恢复只能在脱机的数据文件上恢复 即使有崩溃恢复的时候也要在打开数据库显示调用介质恢复命令 此时崩溃恢复可能没有什么做的但还是会自动运行 有时候介质恢复可能发现没有日志要应用 就会报个错 不需要介质恢复 即该文件不需要恢复

  如果当前控制文件丢失了 将一个备份控制文件还原了 介质恢复就必须做了 这是所有数据文件都联机的时候还要介质恢复的一个例子

     线程合并重做程序

  介质恢复应用重做日志时用的是线程合并的重做算法 即它要同时应用所有线程的重做日志 按SCN递增的顺序合并重做日志 在还原的数据文件上应用介质恢复的过程跟在联机数据文件上应用崩溃恢复的过程的不同在于 崩溃恢复同一时刻只会应用来自一个线程的日志 因为同一时刻数据文件上的块只需要最多一个线程的重做日志(同一时刻只有一个实例可能修改该块) 在还原的备份上 则无法猜测跟该块有关的线程数目 通常介质恢复时需要同时读取所有线程的重做日志 然后按照SCN递增的顺序合并重做日志 注意这个算法依赖于数据块的变更各个线程都是按SCN递增的顺序记录的(并行服务器环境中)

     还原备份

  在数据库关闭或者数据文件脱机的情况下 可以将该数据文件的备份还原 注意决不能在数据文件还在访问的情况下还原 每次都数据文件头时都会校验数据文件头部的检查点计数和数据文件在控制文件中的检查点计数以检测是否发生这种非法操作

     介质恢复命令

  介质恢复命令有三种

  RECOVER DATABASE

  RECOVER TABLESPACE

  RECOVER DATAFILE

  这三个命令的根本区别在于恢复的数据文件集合不同 三个命令都用同样的标准决定每个数据文件是否要做介质恢复 每个数据文件上都一个排它锁 介质恢复程序开始恢复前会先申请获得这个锁 如果得不到就触发一个错误 这可以防止两个恢复会话同时恢复同一个数据文件以及防止对一个在使用的数据文件进行介质恢复

     RECOVER DATABASE

  这个命令用来恢复所有联机数据文件 如果所有实例都正常关闭并且也没有数据文件被还原 这个命令会触发一个 no recovery required 的错误 当有实例已经打开了数据文件时这个命令也会报错因为该实例已经持有所有的锁

     RECOVER TABLESPACE

  这个命令用来恢复指定表空间上的所有数据文件 为了将表空间名转换成具体的数据文件名 数据库必须先打开 这意味着这个表空间及其所有数据文件在数据库打开前得先脱机才能进行介质恢复 如果该表空间的所有数据文件都不需要介质恢复时会触发一个错误说没有文件需要介质恢复

     RECOVER DATAFILE

  这个命令用来恢复指定的数据文件 无论数据库是否打开 只要能获得该数据文件上的介质恢复锁即可 当一个实例已经打开数据库的时候 则只能在脱机的数据文件上做介质恢复

     开始介质恢复

  介质恢复时开始查找介质恢复起始SCN 如所有要恢复的数据文件的文件头中最低的检查点SCN 注意 如果一个数据文件的检查点SCN落在它的脱机SCN范围内(见 )则会引发一个异常 此时 该数据文件的脱机结束SCN将替代文件头检查点SCN参与计算介质恢复起始SCN

  然后每个激活的线程(指在介质恢复开始SCN那一刻处于激活状态的线程 见 )都会分配一个缓冲区用来读取重做日志 每个文件的文件头的检查点SCN被保存下来用来确保在这个SCN以前的重做日志不需要应用 结束SCN(控制文件中记录的)也被保存下来 如果是无穷大则取最大的结束SCN用来告诉介质恢复在何处停止 超出这个SCN的重做日志不需要应用(见 ) 介质恢复结束时 之前结束SCN为无穷大的数据文件会在该结束SCN处做一个检查点操作(而不是在介质恢复结束点) 这使得一个干净脱机或者只读的数据文件在跟它的表空间干净结束SCN处进行检查点操作

     应用重做日志 介质恢复检查点

  每个在介质恢复起始SCN处激活的线程(见 )都打开了一个日志 如果该日志是联机状态 就会自动被打开 如果该日志是归档状态 就会提示用户输入日志名称 除非是自动恢复 所有线程中的重做日志按照产生的顺序被应用 在需要的时候还会切换线程

  有个例外就是在基于取消的不完全恢复(见 )或者是备份的控制文件的恢复(见 ) 按序列顺序计算出的下一个联机日志如果在磁盘上会自动被应用 否则会提示输入它的完整路径

  在日志分界点 介质恢复会执行一个检查点操作 脏数据会被写入到磁盘 数据文件头检查点推进 因此在此之前的重做日志不需要再重新应用 介质恢复的检查点还可能发生在介质恢复结束时会对介质恢复开始时一些结束SCN为无穷大的数据文件在结束SCN处做检查点操作

     介质恢复和模糊状态位

     介质恢复模糊位

  数据文件头部的介质恢复模糊位用来表示由于在进行介质恢复 该数据文件可能包含比数据文件头部检查点SCN还要晚的数据变更 介质恢复模糊位在介质恢复开始的被设置 通常来说在介质恢复对数据文件头发生一次检查点时该状态位可以被清除 当介质恢复成功结束或失败时该状态位才算永久清除 在 将见到 在不完全恢复后以重置日志方式打开数据库 如果还有数据文件的介质恢复模糊位被设置 将会打开失败

     联机模糊位

  介质恢复在碰到一个崩溃恢复结束标记(或者一个立即脱机的标记 发生在数据文件还没有做检查点操作就脱机) 介质恢复会在下一个介质恢复检查点清除数据文件头的联机模糊位和热备模糊位(如果被设置)

     热备份模糊位

  在碰到一个结束热备份标记(或者一个崩溃恢复结束标记) 介质恢复会在下一个介质恢复检查点操作时清除热备份模糊位 在不完全恢复后以重置日志方式打开数据库时如果有数据文件热备份模糊位或其他模糊位被设置 打开将失败 这防止了不完全恢复在热备份开始和结束中间时间点结束时还能以重做日志方式成功打开数据库 在这样的时间点结束不完全恢复将会导致数据文件处于不一致状态 因为还原的备份可能包含该结束点和热备份结束点之间的数据库变更

     线程启用

  当一个实例启用一个新线程的时候会在该线程的重做日志中写入一笔线程启用记录 当介质恢复碰到这样的记录时就重新分配一个重做日志缓冲区 打开新的线程的重做日志 开始应用它的重做日志

     线程禁用

  线程被禁用的时候 它的当前日志被标记为线程结束 介质恢复应用完该重做日志后 会释放它的重做日志缓冲区并停止查找该线程的重做日志

     结束介质恢复(完整的介质恢复)

  每个线程的当前日志(也是最后一个)都会有个线程结束标记 完整的介质恢复(相对于不完全恢复 见 )都会应用重做日志直至所有线程的线程结束处 线程结束标记可以认为是没有当前控制文件 因为线程结束标记在日志头部而不是在控制文件中的记录中

  注意 备份当前联机日志并在后面还原是很危险的 很容易导致对当前线程结束的误判 因为备份中的线程结束标记相对于当前线程结束的日志而言是过期了的

  如果正在做介质恢复的数据文件在控制文件中(假定是当前控制文件)的结束SCN是无穷大 介质恢复将会联机程结束之前停止 重做程序将联机程结束点的SCN处停止 因为没有超出这个SCN的重做日志存在了

  像 中描述的那样 结束SCN是在数据文件脱机时被设置的 如果没有上面这个处理方式 将不能保证数据库打开的时候在结束SCN无穷大的数据文件上的介质恢复何时能停止

     自动恢复

  当介质恢复命令后加上AUTOMATIC选项时将会自动进行介质恢复 它省去了让用户输入归档重做日志文件路径的麻烦 前提是它们在磁盘上 只要日志序号能确定 日志文件名就可以根据数据库初始化参数LOG_ARCHIVE_DEST和LOG_ARCHIVE_FORMAT计算出来 除非用户指定其他的归档目录 当前LOG_ARCHIVE_DEST指定的值将会被使用 介质恢复开始检查点(见 )中包含(RBA字段中)线程(产生该开始检查点的线程)初始的日志序号 如果启用了多个重做日志线程 将根据控制文件中的日志历史记录部分将开始SCN映射到各个线程对应的日志序列号 一旦第一个恢复用的日志找到了 后续的日志按顺序应用 如果不能确定初始的日志序号 用户就得猜测直到找到正确的日志 介质恢复开始检查点中的timestamp字段值将帮助用户决定

     不完全恢复

  RECOVER DATABASE命令可以在所有重做日志被应用前停止 这种类型的恢复就是不完全恢复 不完全恢复后打开数据库必须以重置日志方式打开

  不完全恢复将数据库恢复到指定时间点或之前的数据库一致状态 所有后续的更新将丢失

  不完全恢复主要用于下列情形

  a 因为有文件损坏必须进行介质恢复 但由于某个归档日志或联机日志损坏或丢失 不能进行完全恢复

  b 所有处于激活状态的联机日志都不可用 因此无法进行实例恢复 这个情形变成上一个情形

  c 为了恢复一个用户错误的操作(如删了表或者数据等) 将数据库恢复到错误操作之前的一个数据库一致的点

     Inplete Recovery UNTIL Options

  根据停止的方式分 不完全恢复有三种类型

  a 基于取消的不完全恢复 命令 RECOVER DATABASE UNTIL CANCEL

  b 基于SCN的不完全恢复 命令 RECOVER DATABASE UNTIL CHANGE

  c 基于时间点的不完全恢复 命令 RECOVER DATABASE UNTIL TIME

  基于取消的不完全恢复在用户输入cancel(而不是日志路径)的时候停止恢复 联机日志也不会自动被应用 防止在下一个日志开始前取消 如果多个线程要进行恢复 可能照成某些线程的重做日志只是部分应用

  基于SCN的不完全恢复停止应用指定SCN以及更高SCN相关的重做日志 因此在该SCN时提交的事务(或更晚提交)将会被回滚 如果你想恢复到某个事物提交点SCN时 将将该SCN值加一

  基于时间点的不完全恢复 跟基于SCN的不完全恢复类似 只是输入的是时间点 介质恢复根据重做日志块头部的时间来将该时间点转换成SCN 然后恢复到该SCN处停止

     不完全恢复和数据一致性

  为了防止不完全恢复破坏数据库完整性 所有数据文件必须恢复到同一点 并且没有任何一个数据文件拥有该点之后的数据库变更 这就要求介质恢复用的数据文件必须是从早于期望恢复的时间点之前的备份中还原出来的 系统用文件头的模糊位(见 )来保证数据文件上没有停止时间点之后的变更

     不完全恢复和控制文件记录的数据文件

  如果要不完全恢复到某个数据文件被删除的时间点之前 则控制文件中必须有该被删除的数据文件记录 否则无法进行恢复 而现有的控制文件已经没有该数据文件的记录了 一个可选的方法就是恢复的时候使用删除数据文件之前时间点备份的控制文件进行不完全恢复 另一个可选的方法就是用CREATE CONTROLFILE命令创建一个控制文件包含被删除的数据文件

  不完全恢复到某个数据文件被添加之前的时间点倒没有什么问题 新增的数据文件会在恢复后打开数据库时被忽略 为了避

相关参考

知识大全 Oracle的一个内部工具blockcorruption

Oracle的一个内部工具blockcorruption  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 Oracle内部函数调用追踪器

Oracle内部函数调用追踪器  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  基于以前开发的一个

知识大全 Oracle不完全恢复

Oracle不完全恢复  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Oracle不完全恢复  

知识大全 Oracle误删恢复

Oracle误删恢复  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Oracle误删恢复  qu

知识大全 oracle从备份的控制文件进行完全恢复

  oracle从备份的控制文件进行完全恢复  SYS@orcl#shutdownabort;  ORACLE例程已经关闭  SYS@orcl#  oracle@oracle:~/product//d

知识大全 Oracle索引原理

Oracle索引原理  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Oracle提供了大量索引选

知识大全 Oracle10g恢复试验方法

Oracle认证:Oracle10g恢复试验方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!看了

知识大全 Oracle恢复误操作的表

Oracle恢复误操作的表  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Oracle会把被删除

知识大全 oracle数据库恢复

  没做backup把冷备份复制出来装好oracle  报controlfileversion不匹配oracle版本  试过很多办法都没用最后只好重建controlfile  CREATECONTRO

万用表内部电路主要原理有那些?

  串联电阻的降压作用和并联电阻的分流作用是万用表内部电路的主要原理。