RMAN备份与恢复(新旧控制文件及归档日志)测试

(我的实验)

一直知道我们公司使用的
backup format='G:\20090607rman\datafile\data_%s_%p_%T_%t.bak'
database plus archivelog  delete all input
format 'G:\20090607rman\archivelog\arc_%s_%p_%T_%t.bak';
来进行备份的,当然是LINUX系统,但是由于在家中没有LINUX环境,就改用WINDOWS环境来做,理论是一样的。该语句是进行RMAN的全备加上归档日志的备份,当然也会备份控制文件和SPFILE,但是我有时候就在想如果某一天公司的数据库完全消失了(我说的消失的是某种原因下,数据库完全不存在了,就像被卸载了一样,也许是服务器硬盘完全坏掉了),连DG都不能恢复的情况下,只留下了RMAN的备份(每天公司都会去用系统的TAR进行把所有的备份文件压缩然后ftp到其他地方)
然后需要如何去做那?
很可以确定的可以恢复,但是可以恢复到那个程度?完全恢复是肯定不可能的,因为当前的日志组已经消失了,里面记录的所有操作信息也就没有了,所以数据丢失是肯定的。
现在的疑惑是:1、如果恢复是使用最新的控制文件还是比较就的控制文件,也许很多人会说最新的控制文件,这个确实是对的,但是为了加深印象还是做一次实验。
              2、如果我使用比较旧的控制文件,里面并没有记录新的归档备份集,ORACLE是否可以跨越归档备份集,然后进行恢复?
              3、如果我没有使用delete all input,归档备份到备份集,而且在文件系统中没有删除,是否可以找到?
              4、在RMAN自动全备的时候,控制文件是在数据文件备份前进行,还是之后,这个很重要,涉及到是否能记录当前我们当前备份的数据文件的备份信息。
我就做了这一系列发散,然后开始做实验来解答这一切。(用红色标记试验过程,用粉色标记重点
OK 开始
首先看看当前的日志文件序列
SQL> select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARCHIVED STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- -------- ---------------- ------------- -----------
         1          1        359   52428800          1 NO       CURRENT               10863283 2009-6-7 19
         2          1        357   52428800          1 YES      INACTIVE              10863116 2009-6-7 19
         3          1        358   52428800          1 YES      ACTIVE                10863119 2009-6-7 19
359是当前日志组,然后进行4次切换使用ALTER SYSTEM SWITCH LOGFILE,来模拟真实系统中的日志满后的切换
切换后的日志组为
SQL> select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARCHIVED STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- -------- ---------------- ------------- -----------
         1          1        362   52428800          1 YES      INACTIVE              10863613 2009-6-7 19
         2          1        363   52428800          1 NO       CURRENT               10863615 2009-6-7 19
         3          1        361   52428800          1 YES      INACTIVE              10863610 2009-6-7 19
363是现在的日志组
然后我进行备份使用语句
backup format='G:\20090607rman\datafile\data_%s_%p_%T_%t.bak'
database plus archivelog  delete all input
format 'G:\20090607rman\archivelog\arc_%s_%p_%T_%t.bak';
为了能看清楚我只分配了一个通道,然后贴出所有的备份过程

启动 backup 于 07-6月 -09
当前日志已存档
使用通道 ORA_DISK_1
通道 ORA_DISK_1: 正在启动存档日志备份集
通道 ORA_DISK_1: 正在指定备份集中的存档日志
输入存档日志线程 =1 序列 =359 记录 ID=6 时间戳=688939127
输入存档日志线程 =1 序列 =360 记录 ID=7 时间戳=688939129
输入存档日志线程 =1 序列 =361 记录 ID=8 时间戳=688939133
输入存档日志线程 =1 序列 =362 记录 ID=9 时间戳=688939137
输入存档日志线程 =1 序列 =363 记录 ID=10 时间戳=688939232
通道 ORA_DISK_1: 正在启动段 1 于 07-6月 -09
通道 ORA_DISK_1: 已完成段 1 于 07-6月 -09
段句柄=G:\20090607RMAN\ARCHIVELOG\ARC_2_1_20090607_688939233.BAK 标记=TAG200906
7T200032 注释=NONE
通道 ORA_DISK_1: 备份集已完成, 经过时间:00:00:02
通道 ORA_DISK_1: 正在删除存档日志
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00359_0671122145.001 记录 ID=6 时间戳
=688939127
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00360_0671122145.001 记录 ID=7 时间戳
=688939129
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00361_0671122145.001 记录 ID=8 时间戳
=688939133
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00362_0671122145.001 记录 ID=9 时间戳
=688939137
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00363_0671122145.001 记录 ID=10 时间戳
 =688939232
完成 backup 于 07-6月 -09

启动 backup 于 07-6月 -09
使用通道 ORA_DISK_1
通道 ORA_DISK_1: 启动全部数据文件备份集
通道 ORA_DISK_1: 正在指定备份集中的数据文件
输入数据文件 fno=00001 name=E:\ORADATA\PP\SYSTEM01.DBF
输入数据文件 fno=00003 name=E:\ORADATA\PP\SYSAUX01.DBF
输入数据文件 fno=00002 name=E:\ORADATA\PP\UNDOTBS01.DBF
输入数据文件 fno=00008 name=E:\ORADATA\PP\BIGPP1.DBF
输入数据文件 fno=00005 name=E:\ORADATA\PP\TEST.DBF
输入数据文件 fno=00006 name=E:\ORADATA\PP\PP.DBF
输入数据文件 fno=00004 name=E:\ORADATA\PP\USERS01.DBF
通道 ORA_DISK_1: 正在启动段 1 于 07-6月 -09
通道 ORA_DISK_1: 已完成段 1 于 07-6月 -09
段句柄=G:\20090607RMAN\DATAFILE\DATA_3_1_20090607_688939237.BAK 标记=TAG2009060
T200036 注释=NONE
通道 ORA_DISK_1: 备份集已完成, 经过时间:00:04:56
通道 ORA_DISK_1: 启动全部数据文件备份集
通道 ORA_DISK_1: 正在指定备份集中的数据文件
备份集中包括当前控制文件
在备份集中包含当前的 SPFILE
通道 ORA_DISK_1: 正在启动段 1 于 07-6月 -09
通道 ORA_DISK_1: 已完成段 1 于 07-6月 -09
段句柄=G:\20090607RMAN\DATAFILE\DATA_4_1_20090607_688939533.BAK 标记=TAG2009060
T200036 注释=NONE
通道 ORA_DISK_1: 备份集已完成, 经过时间:00:00:07
完成 backup 于 07-6月 -09

启动 backup 于 07-6月 -09
当前日志已存档
使用通道 ORA_DISK_1
通道 ORA_DISK_1: 正在启动存档日志备份集
通道 ORA_DISK_1: 正在指定备份集中的存档日志
输入存档日志线程 =1 序列 =364 记录 ID=11 时间戳=688939541
通道 ORA_DISK_1: 正在启动段 1 于 07-6月 -09
通道 ORA_DISK_1: 已完成段 1 于 07-6月 -09
段句柄=G:\20090607RMAN\ARCHIVELOG\ARC_5_1_20090607_688939542.BAK 标记=TAG200906
7T200541 注释=NONE
通道 ORA_DISK_1: 备份集已完成, 经过时间:00:00:02
通道 ORA_DISK_1: 正在删除存档日志
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00364_0671122145.001 记录 ID=11 时间戳
 =688939541
完成 backup 于 07-6月 -09

根据顺序能够清楚的看到控制文件是在数据文件备份之后进行的,所以问题4可以解决了。
这里也顺便提下,其实这个备份语句做很好了在备份完后可以看到现在日志组为

SQL> select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARCHIVED STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- -------- ---------------- ------------- -----------
         1          1        365   52428800          1 NO       CURRENT               10863997 2009-6-7 20
         2          1        363   52428800          1 YES      INACTIVE              10863615 2009-6-7 19
         3          1        364   52428800          1 YES      ACTIVE                10863751 2009-6-7 20

实现了两次切换,一次在备份数据文件前一次在之后,这个是为了保证数据文件备份的完整性,避免恢复时的问题。

然后我又进行了3次切换,语句一样,模拟的是一个备份周期,然后日志组序号来到了368
SQL> select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARCHIVED STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- -------- ---------------- ------------- -----------
         1          1        368   52428800          1 YES      ACTIVE                10864109 2009-6-7 20
         2          1        369   52428800          1 NO       CURRENT               10864800 2009-6-7 20
         3          1        367   52428800          1 YES      INACTIVE              10864106 2009-6-7 20
这样又生成了3个归档文件,然后为了节约时间(机器不好,备份很卡),这次我只备份了控制文件和归档日志文件,其实重试验的角度出发效果是一样的。
语句如下:
BACKUP FORMAT 'G:\20090607rman\archivelog\arc_%s_%p_%T_%t.bak' ARCHIVELOG ALL DELETE ALL INPUT;
backup current controlfile format ='G:\20090607rman\controlfile\ctl_%s_%p_%T_%t.bak' ;
同样我贴出备份过程,

启动 backup 于 07-6月 -09
当前日志已存档
使用通道 ORA_DISK_1
通道 ORA_DISK_1: 正在启动存档日志备份集
通道 ORA_DISK_1: 正在指定备份集中的存档日志
输入存档日志线程 =1 序列 =365 记录 ID=12 时间戳=688939757
输入存档日志线程 =1 序列 =366 记录 ID=13 时间戳=688939765
输入存档日志线程 =1 序列 =367 记录 ID=14 时间戳=688939771
输入存档日志线程 =1 序列 =368 记录 ID=15 时间戳=688940100
通道 ORA_DISK_1: 正在启动段 1 于 07-6月 -09
通道 ORA_DISK_1: 已完成段 1 于 07-6月 -09
段句柄=G:\20090607RMAN\ARCHIVELOG\ARC_6_1_20090607_688940101.BAK 标记=TAG2009060
7T201500 注释=NONE
通道 ORA_DISK_1: 备份集已完成, 经过时间:00:00:02
通道 ORA_DISK_1: 正在删除存档日志
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00365_0671122145.001 记录 ID=12 时间戳
 =688939757
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00366_0671122145.001 记录 ID=13 时间戳
 =688939765
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00367_0671122145.001 记录 ID=14 时间戳
 =688939771
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00368_0671122145.001 记录 ID=15 时间戳
 =688940100
完成 backup 于 07-6月 -09

 

启动 backup 于 07-6月 -09
使用通道 ORA_DISK_1
通道 ORA_DISK_1: 启动全部数据文件备份集
通道 ORA_DISK_1: 正在指定备份集中的数据文件
备份集中包括当前控制文件
通道 ORA_DISK_1: 正在启动段 1 于 07-6月 -09
通道 ORA_DISK_1: 已完成段 1 于 07-6月 -09
段句柄=G:\20090607RMAN\CONTROLFILE\CTL_7_1_20090607_688940106.BAK 标记=TAG200906
07T201506 注释=NONE
通道 ORA_DISK_1: 备份集已完成, 经过时间:00:00:06
完成 backup 于 07-6月 -09

当前日志已存档这句话表示日志组又切换了,同样是为了保证归档备份的完整性,有利于恢复。
现在的日志组序列来到了369

SQL> select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARCHIVED STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- -------- ---------------- ------------- -----------
         1          1        368   52428800          1 YES      ACTIVE                10864109 2009-6-7 20
         2          1        369   52428800          1 NO       CURRENT               10864800 2009-6-7 20
         3          1        367   52428800          1 YES      INACTIVE              10864106 2009-6-7 20
到这里我的备份完成了,然后用DBCA删除现在数据库,来模拟数据库消失,然后我新建了一个同名了数据库,应为我恢复SPFILE没有成功,但是这个不是重点,SPFILE记录只是控制文件
的位置和参数,然后我删除了新建数据库中的控制文件日志文件和控制文件,我只要一个SPFILE来启动到NOMOUNT阶段。
然后我做的第一个测试是证明是否可以在控制文件比较旧的情况下没有新的归档日志备份集信息的情况下,来进行恢复,
我这里也就是取第一次备份控制文件然后RESOTRE DATABASE,然后RECOVER ,看是否可以恢复到368这里。
这里贴出列出过程:
RMAN> restore controlfile from 'G:\20090607rman\datafile\DATA_4_1_20090607_68893
9533.BAK';

启动 restore 于 07-6月 -09
使用目标数据库控制文件替代恢复目录
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: sid=156 devtype=DISK

通道 ORA_DISK_1: 正在复原控制文件
通道 ORA_DISK_1: 恢复完成, 用时: 00:00:07
输出文件名=E:\ORADATA\PP\CONTROL01.CTL
输出文件名=E:\ORADATA\PP\CONTROL02.CTL
输出文件名=E:\ORADATA\PP\CONTROL03.CTL
完成 restore 于 07-6月 -09

RMAN> sql 'alter database mount';

sql 语句: alter database mount
释放的通道: ORA_DISK_1

RMAN> list backup;


备份集列表
===================

BS 关键字  大小       设备类型占用时间 完成时间
------- ---------- ----------- ------------ ----------
1       36.38M     DISK        00:00:13     07-6月 -09
        BP 关键字: 1   状态: AVAILABLE  已压缩: NO  标记: TAG20090607T195056
段名:G:\20090607RMAN\ARCHIVELOG\ARC_1_1_20090607_688938657.BAK

  备份集 1 中的已存档日志列表
  Thrd Seq     低 SCN    短时间     下一个 SCN   下一次
  ---- ------- ---------- ---------- ---------- ---------
  1    354     10851174   05-6月 -09 10862844   07-6月 -09
  1    355     10862844   07-6月 -09 10863113   07-6月 -09
  1    356     10863113   07-6月 -09 10863116   07-6月 -09
  1    357     10863116   07-6月 -09 10863119   07-6月 -09
  1    358     10863119   07-6月 -09 10863283   07-6月 -09

BS 关键字  大小       设备类型占用时间 完成时间
------- ---------- ----------- ------------ ----------
2       474.50K    DISK        00:00:01     07-6月 -09
        BP 关键字: 2   状态: AVAILABLE  已压缩: NO  标记: TAG20090607T200032
段名:G:\20090607RMAN\ARCHIVELOG\ARC_2_1_20090607_688939233.BAK

  备份集 2 中的已存档日志列表
  Thrd Seq     低 SCN    短时间     下一个 SCN   下一次
  ---- ------- ---------- ---------- ---------- ---------
  1    359     10863283   07-6月 -09 10863608   07-6月 -09
  1    360     10863608   07-6月 -09 10863610   07-6月 -09
  1    361     10863610   07-6月 -09 10863613   07-6月 -09
  1    362     10863613   07-6月 -09 10863615   07-6月 -09
  1    363     10863615   07-6月 -09 10863751   07-6月 -09

BS 关键字  类型 LV 大小       设备类型 经过时间 完成时间
------- ---- -- ---------- ----------- ------------ ----------
3       Full    896.16M    DISK        00:04:52     07-6月 -09
        BP 关键字: 3   状态: AVAILABLE  已压缩: NO  标记: TAG20090607T200036
段名:G:\20090607RMAN\DATAFILE\DATA_3_1_20090607_688939237.BAK
  备份集 3 中的数据文件列表
  文件 LV 类型 Ckp SCN    Ckp 时间   名称
  ---- -- ---- ---------- ---------- ----
  1       Full 10863756   07-6月 -09 E:\ORADATA\PP\SYSTEM01.DBF
  2       Full 10863756   07-6月 -09 E:\ORADATA\PP\UNDOTBS01.DBF
  3       Full 10863756   07-6月 -09 E:\ORADATA\PP\SYSAUX01.DBF
  4       Full 10863756   07-6月 -09 E:\ORADATA\PP\USERS01.DBF
  5       Full 10863756   07-6月 -09 E:\ORADATA\PP\TEST.DBF
  6       Full 10863756   07-6月 -09 E:\ORADATA\PP\PP.DBF
  8       Full 10863756   07-6月 -09 E:\ORADATA\PP\BIGPP1.DBF


可以看到没有新的备份的归档日志文件信息,只到日志序号363
然后restore recover:
RMAN> restore database;

启动 restore 于 07-6月 -09
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: sid=155 devtype=DISK

通道 ORA_DISK_1: 正在开始恢复数据文件备份集
通道 ORA_DISK_1: 正在指定从备份集恢复的数据文件
正将数据文件00001恢复到E:\ORADATA\PP\SYSTEM01.DBF
正将数据文件00002恢复到E:\ORADATA\PP\UNDOTBS01.DBF
正将数据文件00003恢复到E:\ORADATA\PP\SYSAUX01.DBF
正将数据文件00004恢复到E:\ORADATA\PP\USERS01.DBF
正将数据文件00005恢复到E:\ORADATA\PP\TEST.DBF
正将数据文件00006恢复到E:\ORADATA\PP\PP.DBF
正将数据文件00008恢复到E:\ORADATA\PP\BIGPP1.DBF
通道 ORA_DISK_1: 正在读取备份段 G:\20090607RMAN\DATAFILE\DATA_3_1_20090607_68893
9237.BAK
通道 ORA_DISK_1: 已恢复备份段 1
段句柄 = G:\20090607RMAN\DATAFILE\DATA_3_1_20090607_688939237.BAK 标记 = TAG2009
0607T200036
通道 ORA_DISK_1: 恢复完成, 用时: 00:04:55
完成 restore 于 07-6月 -09

 

RMAN> recover database;

启动 recover 于 07-6月 -09
使用通道 ORA_DISK_1

正在开始介质的恢复

无法找到存档日志
存档日志线程 =1 序列=364

可以看到这里出错了,不能找到364归档日志,这里报错信息是说不能找到,也许是因为我们的文件系统没有这个归档日志文件,如果还在文件系统而没有删除也许还可以恢复,但是这个只是猜测。
但是这里的确证明了问题2,如果我使用比较旧的控制文件,里面并没有记录新的归档备份集,ORACLE是不能跨越归档备份集恢复的。
如果我们使用的是新的控制文件会如何哪?
这里使用前面出错的数据文件,只是RESOTRE 了新的控制文件
然后进行恢复
RMAN> recover database until sequence 368;

启动 recover 于 07-6月 -09
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: sid=156 devtype=DISK

正在开始介质的恢复

通道 ORA_DISK_1: 正在启动到默认目标的存档日志恢复
通道 ORA_DISK_1: 正在恢复存档日志
存档日志线程 =1 序列=364
通道 ORA_DISK_1: 正在读取备份段 G:\20090607RMAN\ARCHIVELOG\ARC_5_1_20090607_6889
39542.BAK
通道 ORA_DISK_1: 已恢复备份段 1
段句柄 = G:\20090607RMAN\ARCHIVELOG\ARC_5_1_20090607_688939542.BAK 标记 = TAG200
90607T200541
通道 ORA_DISK_1: 恢复完成, 用时: 00:00:02
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00364_0671122145.001 线程 =1 序列 =364

通道 ORA_DISK_1: 正在启动到默认目标的存档日志恢复
通道 ORA_DISK_1: 正在恢复存档日志
存档日志线程 =1 序列=365
通道 ORA_DISK_1: 正在恢复存档日志
存档日志线程 =1 序列=366
通道 ORA_DISK_1: 正在恢复存档日志
存档日志线程 =1 序列=367
通道 ORA_DISK_1: 正在读取备份段 G:\20090607RMAN\ARCHIVELOG\ARC_6_1_20090607_6889
40101.BAK
通道 ORA_DISK_1: 已恢复备份段 1
段句柄 = G:\20090607RMAN\ARCHIVELOG\ARC_6_1_20090607_688940101.BAK 标记 = TAG200
90607T201500
通道 ORA_DISK_1: 恢复完成, 用时: 00:00:02
存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00365_0671122145.001 线程 =1 序列 =365

存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00366_0671122145.001 线程 =1 序列 =366

存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00367_0671122145.001 线程 =1 序列 =367

介质恢复完成, 用时: 00:00:06
完成 recover 于 07-6月 -09

这里回复到368,说明了如果要恢复到最近还是应该使用最新的控制文件,证明了问题1

最后是问题3了如果我使用旧的控制文件,但是在备份过程中没有最后的归档信息,结果会如何,这里我贴回来了最归档日志364,365,366,367
试验最后的RECOVER 如下

RMAN> recover database;

启动 recover 于 07-6月 -09
使用通道 ORA_DISK_1

正在开始介质的恢复

存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00364_0671122145.001 线程 =1 序列 =364

存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00365_0671122145.001 线程 =1 序列 =365

存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00366_0671122145.001 线程 =1 序列 =366

存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00367_0671122145.001 线程 =1 序列 =367

存档日志文件名 =E:\ORACLE10GHOME\RDBMS\ARC00367_0671122145.001 线程 =1 序列 =368

然后就是报找不到序号368的错误,当然找不到,我没有贴回368到文件系统归档目录。

而重整个恢复试验来看,可以看到使用的越新的控制文件,里面记录的备份信息也就越新,当然也包括最新的归档日志备份集,这样使用了DELETE ALL INPUT语句的情况可以通过控制文件中记录的归档日志备份集信息,来读取最新的归档备份集,这也就证明了问题1,当然如果你并非想恢复到最新的这个时刻,而是过去的某一点,那就另当别论了。


最后我总结下:
1、如果要恢复到最近的时间,最好使用最新的控制文件,如果要恢复到以前某一点,根据需求要定使用何时的控制文件。
2、如果我使用比较旧的控制文件,里面并没有记录新的归档备份集,ORACLE是不能跨越归档备份集恢复的。
3、如果没有使用delete all input,归档备份到备份集,而且在文件系统中没有删除,是可以找到的。
4、在RMAN自动全备的时候,控制文件是在数据文件备份之后进行备份的。(PS:如果备份中包含了SYSTEM数据文件会自动备份控制文件)

如果就像我开头说的我们公司这样的备份方式,如果数据库消失了(所有文件,也许是服务器坏掉),而且DG不能恢复,最好的方法是取出最近的控制文件,然后使用不完全恢复,最多只会丢失1天的数据


 

上一篇:《构建高可用Linux服务器 第3版》—— 2.7 系统维护时应注意的非技术因素


下一篇:售假获刑后他又被淘宝告上法庭,杭州互联网法院当庭宣判