玩Oracle也有2年的时间了, 零零散散的也整理一些资料。 东西一多了,就理不清楚。 所以结合张晓明的《大话Oracle RAC》的一些内容,和自己整理的一些笔记,对Oracle 的备份和恢复做了一个系统的整理。 也是自己对知识的一个巩固吧。
一. 准备知识
先来看一些准备知识,了解Oracle的物理结构,有如下4种。
1. 数据文件和数据块
Oracle 数据库的存储空间是用表空间来表示的,表空间只是一个逻辑概念,而物理上每个表空间是由磁盘文件组成,这些文件叫做数据文件(Data file),每个表空间可以由一个到多个数据文件组成,每个数据文件被划分为若干个最小的存储单位: 数据块(data block)。
具体参考我的blog: 表空间(tableSpace) 段(segment) 盘区(extent) 块(block) 关系
http://blog.csdn.net/xujinyang/article/details/6829910
Oracle 的用户数据是写到数据块上的,Oracle 是在SGA上操作数据的,修改数据或者添加数据都是在内存中进行,这些被修改的内存不会立即写入磁盘,而是以特定的时间间隔被写入磁盘。 如果哦数据库正常关闭,则在关闭之前将内存中的数据同步到磁盘,这时数据状态是一致的。如果数据库不正常关闭(如宕机,shutdown abort),内存中的内容没有完全写回磁盘,这时数据文件是不一致的。 如果数据文件是从备份中恢复出来的,数据文件也是不一致的,不一致性的数据文件必须恢复到一致的状态。
2. 日志文件
Oracle 数据库日志文件包括 联机日志 和 归档日志, 这些文件都是用来记录数据库修改历史的。Oracle 数据库至少要有两组联机日志,联机日志循环使用,当一组联机日志写满后,就要切换到另一组联机日志,后者的内容就会被覆盖,这个过程叫作日志切换(Log Switch),在日志切换时会触发检查点(CheckPoint)。
数据库的修改操作要记录到日志文件中,并且这个记录动作是在修改数据之前进行的,正因为日志文件中记录了所有的修改历史,因此如果有过去某个时点的备份文件,并且有从那是到当前的所有日志文件,就可以通过在备份文件上“重演”这些日志的方式,把数据文件恢复到当前状态或者之间的任何时点的状态。
日志线程(Redo Thread):
每个实例用到的联机日志就是一个Redo Thread,单实例有且仅有一个Redo Thread。在RAC 环境下,每个实例都需要自己的联机日志,也就是每个实例都有自己的Redo Thread。 这种每实例一个Redo Thread的设计就是为了避免实例间共享Redo 文件引发的竞争,提高系统性能。 但是这也带了一个问题,就是用RMAN 备份RAC 的时候,需要所有的日志文件。 故需要在两个节点上互相把日志传送到另一个节点。
Thread 这个参数用来指定实例使用的Redo Thread 线程号。一般和该实例的INSTANCE_NUMBER 参数相同。 通过视图V$LOG的Thread#列可以确定日志组所属的线程。
注意: 因为RAC 环境下有多个日志线程,所以在添加日志时必须指定线程号。
SQL>alter database add logfile thread 1 group 5 ('/oracle/oradata/redo5') size 50m;
在RAC 环境下,用户操作是分布在多个实例之间的,各实例都有自己的联机日志,恢复时必须把所有实例的联机日志都合并,把Redo Log Record 按照SCN 排序,才能整理出准确的用户操作记录,所以RAC的联机日志必须放在共享存储上,以保证实例都能访问其他实例的联机日志。
在看一个sql 的查询结果:
SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS
---------- ---------- ---------- ---------- ---------- --- ---------------- ----
1 1 24585 104857600 1 YES ACTIVE
2 1 24583 104857600 1 YES INACTIVE
3 1 24584 104857600 1 YES INACTIVE
8 1 24586 104857600 1 NO CURRENT
从查询结果上,我们可以看到联机日志有3个状态。
INACTIVE: 表示DBWR 已经做完,该日志包含的数据修改已经写到数据文件
ACTIVE: DBWR 没有做完,数据还没有写到数据文件。
CURRENT:当前正在使用的日志。 没有DBWR 操作。
RedoLog Checkpoint 和 SCN关系
http://blog.csdn.net/xujinyang/article/details/6829693
Redo Log 和Checkpoint not complete
http://blog.csdn.net/xujinyang/article/details/6832719
Oracle 归档与非归档的切换
http://blog.csdn.net/xujinyang/article/details/6830327
log file sync(日志文件同步) 与 Log file parallel write 等待事件
http://blog.csdn.net/xujinyang/article/details/6829947
3. 控制文件
控制文件记录了数据库的物理结构和状态(比如数据文件名,每个数据文件的检查点号,联机状态),包括备份和恢复的信息也记录在控制文件中。 恢复过程要根据控制文件中的信息,比如数据库的检查点,当前联机日志,数据文件检查点等来进行恢复操作,如果控制文件丢失,则恢复的过程会很艰难。
控制文件里包含的具体信息,参考我的Blog:
Oracle 控制文件
http://blog.csdn.net/xujinyang/article/details/6829884
4. Undo Segment
修改记录过程中,记录修改之前的状态会被记录到Undo Segment中, 这条记录叫作前镜像(before images)。 当需要撤销修改比如执行Rollback时,就用这条前镜像覆盖现有记录,对于Insert 操作,前镜像就是一个空记录,对于Undate,Delete 操作,前镜像就是修改之前的记录。
在数据库恢复过程中,日志和Undo Segment 共同起作用,二者保证了最终恢复的一致状态。二者也对应了恢复的两个阶段: 前滚(Roforware)和 回滚(Rollback)。在前滚阶段,在文件上重演日志内容,以把文件恢复到数据库关闭时的状态,但是数据库关闭时可能有很多修改操作没有提交,这些操作必须进行回滚,这就要利用Undo Segment的内容。
Oracle undo 回滚段管理
http://blog.csdn.net/xujinyang/article/details/6822971
二.备份
备份是指数据的拷贝,这个拷贝可以用来重建数据库。 备份可以分为物理备份和逻辑备份。
物理备份: 指对数据文件,控制文件,联机日志文件等文件进行物理拷贝的方法,这种方法是在文件层进行的,通过冗余的文件备份来体统数据保护。物理备份又可分为联机备份(也叫作联机热备)和脱机备份(也称冷备)。
逻辑备份: 利用Oracle 提供的导出工具把重要数据导出到文件,以后恢复时在利用工具把数据重新导入到数据库中,这种保护是在数据层进行的。 该类工具有: exp/imp, expdp/impdp(10g 以后版本)。
物理备份是最强健的数据保护方也,也是备份策略中首选的方法,逻辑备份只能作为物理备份的补充手段,不足以保护数据丢失。
物理备份又可分为用户管理备份(User-Managed Backup)和RMAN备份(Recovery Manager)。 前者是联合使用SQL 命令和OS的cp 命来进行文件备份。 Rman 备份指利用RMAN 工具来进行备份。
Rman 备份有几点好处:
1. 增量备份
2. 数据块恢复:可以在新进行数据块恢复,不必进行数据文件恢复,提高系统的可用性。
3. 压缩备份
4. 加密备份
具体用法参考blog:
RMAN 备份与恢复 实例
http://blog.csdn.net/xujinyang/article/details/6822620
Oracle Rman 命令详解(List report backup configure)
http://blog.csdn.net/xujinyang/article/details/6838072
Oracle Rman跨resetlogs版本恢复
http://blog.csdn.net/xujinyang/article/details/6830337
ORACLE 数据库逻辑备份 简单 EXP/IMP
http://blog.csdn.net/xujinyang/article/details/6830199
Oracle 10g EXPDP和IMPDP使用说明
http://blog.csdn.net/xujinyang/article/details/6830446
三.恢复
3.1 理论知识:
Oracle 在运行过程中,所有对于数据的修改都是在内存中进行,Oracle 每要修改一个记录必须先把记录所在的数据块加载到内存中,然后在内存中进行修改。但是提交(commit)时,修改的数据块不会立即写回磁盘。基于性能考虑,Oracle是采用“延时写”的算法定期批量的把数据块写回磁盘。因此在数据库运行过程中,内存的内容总是比磁盘数据新。 当数据库正常关闭时(Shutdown Immediate,shutdown normal,shutdown tracsactional),Oracle 会把SGA内容全部写回磁盘后才关闭数据库,这时内存和磁盘就完全同步了。 所以正常关闭数据库后数据不会丢失,但是如果数据库是异常关闭(突然短线,shutdown abort),内存中的数据来不及同步到磁盘,这是就会产生了数据不一致,Oracle 在次打开数据库时,就需要进行实例恢复。
Oracle 的Redo 机制保证了数据库恢复的可行性,在修改数据之前,代表本次修改操作的Redo记录必须先被保存下来(Write Ahead Logging),然后才真正修改数据记录。在处理commit语句时,Oracle 会在Log buffer产生一条commit 记录,为了保证事务的持久化,所有Redo 记录和这一条commit记录都要被写到磁盘的联机日志文件(Log Force At commit),但是数据块(Data Block)不必写回磁盘。 如果联机日志空间不够,还会触发日志切换(Log Switch),旧日志的检查点必须完成才能被覆盖,如果采用归档模式,这个日志还必须完成归档才能覆盖。
这些日志中都会带有SCN,SCN类似于时间戳,Oracle 按照SCN对日志内容进行排序,就可以得到操作历史,Oracle 也是根据SCN来判断数据文件是否需要恢复的。
数据库在正常运行时,每个数据文件的终止SCN(STOP SCN)会被设置为无穷大(NULL),而其他的那些SCN应该完全一样。如果数据库正常关闭,关闭之前会执行一个检查点动作,每个数据文件的终止SCN 会被设置成启动SCN(Start SCN)。 如果数据库异常关闭,终止SCN 来不及设置为启动SCN,仍然保持NULL。
当clean shutdown 时,checkpoint会进行,并且此时datafile的stop scn和start scn会相同。 等到我们开启数据库时,Oracle检查datafile header中的start scn和存于control file中的datafile的scn是否相同, 如果相同,接着检查start scn和stop scn是否相同,如果仍然相同,数据库就会正常开启,否则就需要recovery... 等到数据库开启后,储存在control file中的stop scn就会恢复为NULL值,此时表示datafile是open在正常模式下了。
如果不正常SHUTDOWN (shutdown abort),则mount数据库后,你会发现stop scn并不是等于其它位置的scn, 而是等于NULL,这表示Oracle在shutdown时没有进行checkpoint,下次开机必须进行crash recovery。
注意:当发生checkpoint时,会把SCN写到四个地方去。三个地方于control file内,一个在datafile header。
Control file三个地方为
1.System checkpoint SCN
2.2.Datafile checkpoint SCN
3.Stop SCN
另外一个地方在datafile header内
4.Start SCN
更多内容参看blog: RedoLog Checkpoint 和 SCN关系
http://blog.csdn.net/xujinyang/article/details/6829693
Oracle恢复可以分成实例恢复(Instance Recovery),介质恢复(Media Recovey),其中介质恢复又可分为完全恢复(Complete Recovery)和不完全恢复(Incomplete Recovery)。
3.2 恢复种类
3.2.1 Instance Recovery -- 由Oracle 自动完成,无需DBA 干预
如果实例异常关闭(宕机,shutdown abort),并且数据文件,控制文件,联机日志都没有丢失。在下次启动时,要利用联机日志的内容进行恢复,这种恢复就是实例恢复(Instance Recovery)。
Instance Recovery 主要包括3个阶段:
1) 根据联机日志内容进行Rollover。
2) 打开数据库,提供服务
3) SMON 或者用户进程进行Rollback。
3.2.2 Media Recovery
如果发生数据文件丢失或者破坏,就需要使用备份和归档日志来进行恢复, 这种恢复就是 介质恢复,它需要有备份,归档日志,联机日志一起才能完成。又分为 安全恢复和不完全恢复两种。
3.2.3 Crash Recovery -- 由Oracle 自动完成。
Instance Recovery是实例发生Crash 后进行的Recovery,这种恢复是在故障节点进行,而RAC 中的Crash Recovery 是某个实例发生Crash 后在其他实例上进行的Recovery。 这种Recovery 有一个特殊要求:在健康节点执行Crash Recovery时,必须要保证故障节点不能在对共享数据进行操作,也就是要对故障节点进行IO 隔离(IO Fencing),这是由CSS服务来保证的。
在Crash Recovery过程中PCM Lock起到了重要作用,恢复实例(执行Recovery动作的实例)根据数据块的PCM-Lock 状态来决定数据块是否需要进行恢复。
Crash Recovery 可分为3个阶段:
1)First-Pass Log Read
2)Recovery Claim Locking
3)Second-Pass Log Read
3.2.4 Online Block Recovery
Online Block Recovery 是RAC所特有的, 如果某个用户进程在修改数据时异常死掉,导致SGA的Data buffer数据不一致,或者说Data Buffer被破坏,这时就会触发Online Block Recovery,这个动作可有PMON进程或者前台进程完成。这个恢复过程需要一个恢复起点, 这个起点就是最近的Past Image。
3.3 介质恢复
介质恢复指磁盘介质发生损坏,导致数据文件无法访问,这时必须利用备份文件在新的磁盘上恢复出数据文件。
3.3.1 完全恢复
它是把数据库恢复到发生故障时的状态,名字中的完全指没有任何数据损失,要实现这个目标,必须满足一定的条件: 备份,从备份之后的所有归档日志,联机日志都可用。
完全恢复是最简单的一种恢复, 只需要两个命令: restore database 和 recover database。
这2个命令的具体用法参考我的Blog: RMAN 备份与恢复 实例, 里面有详细的例子
http://blog.csdn.net/xujinyang/article/details/6822620
在次补充一点知识: RECOVER DATABASE UNTIL CANCEL 和 RECOVER DATABASE UNTIL CANCEL USING BACKUP CONTROLFILE区别
1) RECOVER DATABASE UNTIL CANCEL
==> DATAFILE HEADER SCN一定会小于CONTROLFILE的DATAFILE SCN
如果你有进行RESTORE DATAFILE,则该RESTORE的DATAFILE HEADER SCN一定会小于目前CONTROLFILE的DATAFILE SCN,此时会无法开启数据库,必须进行media recovery。 重做archive log直到该datafile header的SCN=current scn
2) RECOVER DATABASE UNTIL CANCEL USING BACKUP CONTROLFILE;
==> DATAFILE HEADER SCN一定会大于CONTROLFILE的DATAFILE SCN
如果只是某TABLE被DROP掉,没有破坏数据库整体数据结构,还可以用NCOMPLETE RECOVERY解决 如果是某个TABLESPACE OR DATAFILE被DROP掉,因为档案结构已经破坏,目前的CONTROL FILE内已经没有 该DATAFILE的信息,就算你只RESTORE DATAFILE然后进行INCOMPLETE RECOVERY也无法救回被DROP的DATA FILE。
只好RESOTRE 之前备份的CONTROL FILE(里头被DROP DATAFILE Metadata此时还存在),不过RESTOREC CONTROL FILE后 此时Oracle会发现CONTROL FILE内的SYSTEM SCN会小于目前的DATAFILE HEADER SCN,也不等于目前储存于LOG FILE内的SCN, 此时就必须使用RECOVER DATABASE UNTIL CANCEL USING BACKUP CONTROLFILE到DROP DATAFILE OR DROP TABLESPACE之前的SCN。
3.3.2 不完全恢复
不完全恢复是指数据库无法恢复到发生故障那一点的状态,而只能恢复到之前一段时间的状态,这就以为着承受一定量的数据损失。
Oracle 运行时包括参数文件,控制文件,数据文件,联机日志,那么哪些文件会导致不完全恢复呢?
参数文件只是一个文本文件,丢失没有关系。控制文件通常有多个文件相互冗余。 而且在做全库备份时,控制文件会被自动备份,故所有文件都损坏,也可以通过备份进行恢复,即使没有备份,也可以通过重建控制文件来恢复,也不会造成数据丢失。如果是数据文件损坏,只要有备份和备份后的完整的日志文件,也可以完成恢复,不会造成数据丢失。
联机日志比较特殊,通过前面的介绍,我们知道在数据库异常关机的情况下,它可能造成数据丢失。
我们来看一下联机日志损坏的恢复方法:
先用SQL 查看一下出问题的联机日志是什么状态:
SQL> Select thread#,group#,status from v$log;
1)如果是Inactive 状态的联机日志,因为它里面的记录已经同步到数据文件,所以只需要把该日志删掉即可。
2)如果是Active/ current 状态的连接日志, 因为他们里面有记录没有同步到数据文件,可以通过如下方式来恢复:
(1)关闭所有实例
(2)在受损实例上,启动到mount状态
(3)执行alter database open resetlogs
(4)如果在第三步出现错误,并其实需要不完全恢复,就执行一下: recover database until cancel
(5)实例启动成功后,启动其他实例
(6)立即对数据库进行一次全备。
说明: 在做了alter database open resetlogs;会把online redelog file清空,数据文件丢失.所以这个时候要做一个全备份。resetlogs命令表示一个数据库逻辑生存期的结束和另一个数据库逻辑生存期的开始,每次使用resetlogs命令的时候,SCN不会被重置,不过oracle会重置日志序列号,而且会重置联机重做日志内容.这样做是为了防止不完全恢复后日志序列会发生冲突(因为现有日志和数据文件间有了时间差)。