这里假定是nocatalog的情况下,我们采用了RMAN备份,但是丢失了控制文件,因为控制文件中包含了rman的备份信息,所以没有办法用平常的方法来恢复,如果想恢复数据库,则需要利用一个叫DBMS_BACKUP_RESTORE的包来实现,这个包在nomount下就可以正常运行,也就是说,只需要启动到nomount下就可以利用它来恢复控制文件或者数据文件以及归档日志。
1、从备份片中恢复控制文件
最好有控制文件能恢复,就算恢复的这个控制文件没有最新的备份信息也好,起码可以利用它来定位数据文件。如果没有控制文件可恢复,后来的数据文件恢复将变的更复杂。以下是恢复控制文件的脚本,需要在sys as dba的连接下执行。
- DECLARE
- v_dev varchar2(50); /* 设备类型 */
- v_done boolean; /* 恢复(restore)完成标志 */
- type t_fileTable is table of varchar2(255) index by binary_integer;
- v_fileTable t_fileTable; /* 备份片的名字 */
- v_maxPieces number:=1; /* 备份片的个数 */
- BEGIN
- /*首先定义可以用的备份片与备份片的个数 */
- v_fileTable(1):='fulldb_s15_p1';
- v_fileTable(2):='fulldb_s15_p2';
- v_fileTable(3):='fulldb_s15_p3';
- v_fileTable(4):='fulldb_s15_p4';
- v_maxPieces:=4;
- /*分配设备类型,如果是磁带,则是sbt_tape,如果是磁盘,则是null*/
- v_dev:=sys.dbms_backup_restore.deviceAllocate(type=>'sbt_tape', ident=>'t1');
- sys.dbms_backup_restore.restoreSetDatafile;
- /*要恢复的控制文件路径与文件名称,文件名称要求正确*/
- sys.dbms_backup_restore.restoreControlfileTo(cfname=>'/u1/oradata/dbs/ctrl1V804.ctl');
- /*开始恢复*/
- FOR i IN 1..v_maxPieces LOOP
- sys.dbms_backup_restore.restoreBackupPiece(done=>v_done,
- handle=>v_fileTable(i),
- params=>null);
- IF v_done THEN
- GOTO all_done;
- END IF;
- END LOOP;
- <<all_done>>
- /* 释放设备 */
- sys.dbms_backup_restore.deviceDeallocate;
- END;
- /
2、从备份片中恢复数据文件
恢复数据文件的时候,必须要知道数据文件对应的文件编号,而且最好能知道数据文件位于哪个备份片,所以就是前面说的最好能先resotre一个控制文件出来,如果实在不行,能用备份时候的日志也可以。以下是恢复全备份的下的数据文件的脚本:
- DECLARE
- v_dev varchar2(50); /* 设备类型 */
- v_done boolean:=false; /* 恢复(restore)完成标志 */
- type t_fileTable is table of varchar2(255) index by binary_integer;
- v_fileTable t_fileTable; /* 备份片的名字 */
- v_maxPieces number:=1; /* 备份片的个数 */
- BEGIN
- /* 初始化备份片 */
- v_fileTable(1):='fulldb_s15_p1';
- v_fileTable(2):='fulldb_s15_p2';
- v_fileTable(3):='fulldb_s15_p3';
- v_fileTable(4):='fulldb_s15_p4';
- v_maxPieces:=4;
- /* 设备类型,磁带:sbt_tape,磁盘:null */
- v_dev:=sys.dbms_backup_restore.deviceAllocate(type=>'sbt_tape',ident=>'t1');
- sys.dbms_backup_restore.restoreSetDatafile;
- /* 要恢复的文件,指定文件号与文件名称 */
- sys.dbms_backup_restore.restoreDataFileTo(dfnumber=>1,
- toname=>'/u1/oradata/dbs/sysV804.dbf');
- /* 恢复数据文件 */
- FOR i IN 1..v_maxPieces LOOP
- sys.dbms_backup_restore.restoreBackupPiece(done=>v_done,
- handle=>v_fileTable(i),
- params=>null);
- IF v_done THEN
- GOTO all_done;
- END IF;
- END LOOP;
- <<all_done>>
- /* 释放设备 */
- sys.dbms_backup_restore.deviceDeallocate;
- END;
- /
当然,有的时候,我们不仅仅是做全备份,还要做增量备份,那么我们怎么从增量备份中应用备份到数据文件中呢,我们可以参考如下脚本:
- DECLARE
- v_dev varchar2(50); /* 设备类型 */
- v_done boolean:=false; /* 恢复(restore)完成标志 */
- type t_fileTable is table of varchar2(255) index by binary_integer;
- v_fileTable t_fileTable; /* 备份片的名字 */
- v_maxPieces number:=1; /* 备份片的个数 */
- BEGIN
- /* 初始化备份片,这里指的是增量备份的备份片 */
- v_fileTable(1):='fulldb_level2_s18_p1';
- v_maxPieces:=1;
- /* 设备类型,磁带:sbt_tape,磁盘:null */
- v_dev:=sys.dbms_backup_restore.deviceAllocate(type=>'sbt_tape',ident=>'t1');
- sys.dbms_backup_restore.applySetDataFile;
- /* 如果合并的数据文件,也就是需要从增量中恢复部分新的块到该数据文件中去 */
- sys.dbms_backup_restore.applyDataFileTo(dfnumber=>1,
- toname=>'/u1/oradata/dbs/sysV804.dbf');
- /* 恢复数据文件 */
- FOR i IN 1..v_maxPieces LOOP
- sys.dbms_backup_restore.applyBackupPiece(done=>v_done,
- handle=>v_fileTable(i),
- params=>null);
- IF v_done THEN
- GOTO all_done;
- END IF;
- END LOOP;
- <<all_done>>
- /* 释放设备 */
- sys.dbms_backup_restore.deviceDeallocate;
- END;
- /
3、从备份片中恢复归档日志
如果restore完数据文件,归档日志也是可能需要做restore的,用于做recover,可以采用如下的脚本恢复archive log:
- DECLARE
- v_dev varchar2(50); /* 设备类型 */
- v_done boolean:=false; /* 恢复(restore)完成标志 */
- type t_fileTable is table of varchar2(255) index by binary_integer;
- v_fileTable t_fileTable; /* 备份片的名字 */
- v_maxPieces number:=1; /* 备份片的个数 */
- BEGIN
- /* 初始化备份片,归档日志的备份片 */
- v_fileTable(1):='al_s20_p1';
- v_fileTable(2):='al_s20_p2';
- v_maxPieces:=2;
- /* 设备类型,磁带:sbt_tape,磁盘:null */
- v_dev:=sys.dbms_backup_restore.deviceAllocate(type=>'sbt_tape',ident=>'t1');
- sys.dbms_backup_restore.restoreSetArchivedLog(destination=>'/app/oracle/admin/arch/arch_');
- /* 归档日志的序列号 */
- sys.dbms_backup_restore.restoreArchivedLog(thread=>1, sequence=>100);
- /* 开始恢复 */
- FOR i IN 1..v_maxPieces LOOP
- sys.dbms_backup_restore.restoreBackupPiece(done=>v_done,
- handle=>v_fileTable(i),
- params=>null);
- IF v_done THEN
- GOTO all_done;
- END IF;
- END LOOP;
- <<all_done>>
- /* 释放通道 */
- sys.dbms_backup_restore.deviceDeallocate;
- END;
- /
以上是恢复一个归档日志的脚本,如果是恢复批量的归档日志,可以采用增加如下内容在上面的脚本中
- for seq in <min seq#>..<max seq#> loop
- sys.dbms_backup_restore.restoreArchivedLog(thread=>1,
- sequence=>seq);
- end loop
注:以上的脚本来自metalink