rman备份丢失控制文件,利用dbms_backup_restore恢复

 
 

这里假定是nocatalog的情况下,我们采用了RMAN备份,但是丢失了控制文件,因为控制文件中包含了rman的备份信息,所以没有办法用平常的方法来恢复,如果想恢复数据库,则需要利用一个叫DBMS_BACKUP_RESTORE的包来实现,这个包在nomount下就可以正常运行,也就是说,只需要启动到nomount下就可以利用它来恢复控制文件或者数据文件以及归档日志。

1、从备份片中恢复控制文件

最好有控制文件能恢复,就算恢复的这个控制文件没有最新的备份信息也好,起码可以利用它来定位数据文件。如果没有控制文件可恢复,后来的数据文件恢复将变的更复杂。以下是恢复控制文件的脚本,需要在sys as dba的连接下执行。

  1. DECLARE
  2. v_dev varchar2(50); /* 设备类型 */
  3. v_done boolean; /* 恢复(restore)完成标志 */
  4. type t_fileTable is table of varchar2(255) index by binary_integer;
  5. v_fileTable t_fileTable; /* 备份片的名字 */
  6. v_maxPieces number:=1; /* 备份片的个数 */
  7. BEGIN
  8. /*首先定义可以用的备份片与备份片的个数 */
  9. v_fileTable(1):='fulldb_s15_p1';
  10. v_fileTable(2):='fulldb_s15_p2';
  11. v_fileTable(3):='fulldb_s15_p3';
  12. v_fileTable(4):='fulldb_s15_p4';
  13. v_maxPieces:=4;
  14. /*分配设备类型,如果是磁带,则是sbt_tape,如果是磁盘,则是null*/
  15. v_dev:=sys.dbms_backup_restore.deviceAllocate(type=>'sbt_tape', ident=>'t1');
  16. sys.dbms_backup_restore.restoreSetDatafile;
  17. /*要恢复的控制文件路径与文件名称,文件名称要求正确*/
  18. sys.dbms_backup_restore.restoreControlfileTo(cfname=>'/u1/oradata/dbs/ctrl1V804.ctl');
  19. /*开始恢复*/
  20. FOR i IN 1..v_maxPieces LOOP
  21.    sys.dbms_backup_restore.restoreBackupPiece(done=>v_done,
  22. handle=>v_fileTable(i),
  23. params=>null);
  24.    IF v_done THEN
  25.    GOTO all_done;
  26.    END IF;
  27. END LOOP;
  28. <<all_done>>
  29. /* 释放设备 */
  30. sys.dbms_backup_restore.deviceDeallocate;
  31. END;
  32. /

2、从备份片中恢复数据文件

恢复数据文件的时候,必须要知道数据文件对应的文件编号,而且最好能知道数据文件位于哪个备份片,所以就是前面说的最好能先resotre一个控制文件出来,如果实在不行,能用备份时候的日志也可以。以下是恢复全备份的下的数据文件的脚本:

  1. DECLARE
  2. v_dev varchar2(50); /* 设备类型 */
  3. v_done boolean:=false; /* 恢复(restore)完成标志 */
  4. type t_fileTable is table of varchar2(255) index by binary_integer;
  5. v_fileTable t_fileTable; /* 备份片的名字 */
  6. v_maxPieces number:=1; /* 备份片的个数 */
  7. BEGIN
  8. /* 初始化备份片 */
  9. v_fileTable(1):='fulldb_s15_p1';
  10. v_fileTable(2):='fulldb_s15_p2';
  11. v_fileTable(3):='fulldb_s15_p3';
  12. v_fileTable(4):='fulldb_s15_p4';
  13. v_maxPieces:=4;
  14. /* 设备类型,磁带:sbt_tape,磁盘:null */
  15. v_dev:=sys.dbms_backup_restore.deviceAllocate(type=>'sbt_tape',ident=>'t1');
  16. sys.dbms_backup_restore.restoreSetDatafile;
  17. /* 要恢复的文件,指定文件号与文件名称 */
  18. sys.dbms_backup_restore.restoreDataFileTo(dfnumber=>1,
  19. toname=>'/u1/oradata/dbs/sysV804.dbf');
  20. /* 恢复数据文件 */
  21. FOR i IN 1..v_maxPieces LOOP
  22.    sys.dbms_backup_restore.restoreBackupPiece(done=>v_done,
  23. handle=>v_fileTable(i),
  24. params=>null);
  25.    IF v_done THEN
  26.    GOTO all_done;
  27.    END IF;
  28. END LOOP;
  29. <<all_done>>
  30. /* 释放设备 */
  31. sys.dbms_backup_restore.deviceDeallocate;
  32. END;
  33. /

当然,有的时候,我们不仅仅是做全备份,还要做增量备份,那么我们怎么从增量备份中应用备份到数据文件中呢,我们可以参考如下脚本:

  1. DECLARE
  2. v_dev varchar2(50); /* 设备类型 */
  3. v_done boolean:=false; /* 恢复(restore)完成标志 */
  4. type t_fileTable is table of varchar2(255) index by binary_integer;
  5. v_fileTable t_fileTable; /* 备份片的名字 */
  6. v_maxPieces number:=1; /* 备份片的个数 */
  7. BEGIN
  8. /* 初始化备份片,这里指的是增量备份的备份片 */
  9. v_fileTable(1):='fulldb_level2_s18_p1';
  10. v_maxPieces:=1;
  11. /* 设备类型,磁带:sbt_tape,磁盘:null */
  12. v_dev:=sys.dbms_backup_restore.deviceAllocate(type=>'sbt_tape',ident=>'t1');
  13. sys.dbms_backup_restore.applySetDataFile;
  14. /* 如果合并的数据文件,也就是需要从增量中恢复部分新的块到该数据文件中去 */
  15. sys.dbms_backup_restore.applyDataFileTo(dfnumber=>1,
  16.    toname=>'/u1/oradata/dbs/sysV804.dbf');
  17. /* 恢复数据文件 */
  18. FOR i IN 1..v_maxPieces LOOP
  19.    sys.dbms_backup_restore.applyBackupPiece(done=>v_done,
  20.    handle=>v_fileTable(i),
  21.    params=>null);
  22.    IF v_done THEN
  23.    GOTO all_done;
  24.    END IF;
  25. END LOOP;
  26. <<all_done>>
  27. /* 释放设备 */
  28. sys.dbms_backup_restore.deviceDeallocate;
  29. END;
  30. /

3、从备份片中恢复归档日志

如果restore完数据文件,归档日志也是可能需要做restore的,用于做recover,可以采用如下的脚本恢复archive log:

  1. DECLARE
  2. v_dev varchar2(50); /* 设备类型 */
  3. v_done boolean:=false; /* 恢复(restore)完成标志 */
  4. type t_fileTable is table of varchar2(255) index by binary_integer;
  5. v_fileTable t_fileTable; /* 备份片的名字 */
  6. v_maxPieces number:=1; /* 备份片的个数 */
  7. BEGIN
  8. /* 初始化备份片,归档日志的备份片 */
  9.    v_fileTable(1):='al_s20_p1';
  10.    v_fileTable(2):='al_s20_p2';
  11.    v_maxPieces:=2;
  12. /* 设备类型,磁带:sbt_tape,磁盘:null */
  13. v_dev:=sys.dbms_backup_restore.deviceAllocate(type=>'sbt_tape',ident=>'t1');
  14. sys.dbms_backup_restore.restoreSetArchivedLog(destination=>'/app/oracle/admin/arch/arch_');
  15. /* 归档日志的序列号 */
  16. sys.dbms_backup_restore.restoreArchivedLog(thread=>1, sequence=>100);
  17. /* 开始恢复 */
  18. FOR i IN 1..v_maxPieces LOOP
  19.    sys.dbms_backup_restore.restoreBackupPiece(done=>v_done,
  20. handle=>v_fileTable(i),
  21. params=>null);
  22.    IF v_done THEN
  23.    GOTO all_done;
  24.    END IF;
  25. END LOOP;
  26. <<all_done>>
  27. /* 释放通道 */
  28. sys.dbms_backup_restore.deviceDeallocate;
  29. END;
  30. /

以上是恢复一个归档日志的脚本,如果是恢复批量的归档日志,可以采用增加如下内容在上面的脚本中

  1. for seq in <min seq#>..<max seq#> loop
  2.    sys.dbms_backup_restore.restoreArchivedLog(thread=>1,
  3.    sequence=>seq);
  4. end loop

注:以上的脚本来自metalink

原文地址:https://www.cnblogs.com/weaver1/p/2491030.html