利用dbms_backup_restore恢复数据库

1. 模拟做一个数据库的RMAN全备
(RMAN备份的日志很重要,特别是数据文件号和名称的对应关系)

C:\Documents and Settings\alex hou>rman target /

恢复管理器: Release 10.2.0.1.0 - Production on 星期二 9月 23 14:07:47 2008

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

连接到目标数据库: ALEX (DBID=1941212992)

RMAN> backup full format 'd:\oracle\oradata\full_%U.bak' database;

启动 backup 于 23-9月 -08
使用目标数据库控制文件替代恢复目录
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: sid=138 devtype=DISK
通道 ORA_DISK_1: 启动全部数据文件备份集
通道 ORA_DISK_1: 正在指定备份集中的数据文件
输入数据文件 fno=00001 name=D:\ORACLE\ORADATA\ALEX\SYSTEM01.DBF
输入数据文件 fno=00003 name=D:\ORACLE\ORADATA\ALEX\SYSAUX01.DBF
输入数据文件 fno=00002 name=D:\ORACLE\ORADATA\ALEX\UNDOTBS01.DBF
输入数据文件 fno=00004 name=D:\ORACLE\ORADATA\ALEX\USERS01.DBF
通道 ORA_DISK_1: 正在启动段 1 于 23-9月 -08
通道 ORA_DISK_1: 已完成段 1 于 23-9月 -08
段句柄=D:\ORACLE\ORADATA\FULL_01JRAKVT_1_1.BAK 标记=TAG20080923T140901 注释=NONE
通道 ORA_DISK_1: 备份集已完成, 经过时间:00:00:45
通道 ORA_DISK_1: 启动全部数据文件备份集
通道 ORA_DISK_1: 正在指定备份集中的数据文件
备份集中包括当前控制文件
在备份集中包含当前的 SPFILE
通道 ORA_DISK_1: 正在启动段 1 于 23-9月 -08
通道 ORA_DISK_1: 已完成段 1 于 23-9月 -08
段句柄=D:\ORACLE\ORADATA\FULL_02JRAL1B_1_1.BAK 标记=TAG20080923T140901 注释=NONE
通道 ORA_DISK_1: 备份集已完成, 经过时间:00:00:03
完成 backup 于 23-9月 -08

2. 关闭数据库,并删除所有数据文件和控制文件

3. 启动数据库到nomount,并从备份集中恢复控制文件

SQL> startup nomount
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              79693156 bytes
Database Buffers           83886080 bytes
Redo Buffers                2945024 bytes
SQL> declare
  2    v_dev varchar2(256);
  3    v_done boolean;
  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    v_fileTable(1):='D:\ORACLE\ORADATA\FULL_01JRAKVT_1_1.BAK';
  9    v_fileTable(2):='D:\ORACLE\ORADATA\FULL_02JRAL1B_1_1.BAK';
 10    v_maxPieces:=2;
 11    /*分配设备类型,如果是磁带,则是sbt_tape,如果是磁盘,则是null*/ 
 12    v_dev:=sys.dbms_backup_restore.deviceAllocate(type=>'', ident=>'t1');
 13    sys.dbms_backup_restore.restoreSetDatafile;
 14    sys.dbms_backup_restore.restoreControlfileTo(cfname=>'D:\Oracle\oradata\alex\control01.ctl');
 15    FOR i IN 1..v_maxPieces LOOP
 16      sys.dbms_backup_restore.restoreBackupPiece(done=>v_done, handle=>v_fileTable(i), params=>null);
 17      IF v_done THEN
 18        GOTO all_done;
 19      END IF;
 20    END LOOP;
 21  <>
 22    sys.dbms_backup_restore.deviceDeallocate;
 23  END;
 24  /
declare
*
第 1 行出现错误:
ORA-19697: ??????????????
ORA-06512: ? "SYS.X$DBMS_BACKUP_RESTORE", line 5149
ORA-06512: ? line 15

由上可见,备份集合中没有control file的信息,无法恢复。

4. 直接恢复数据文件

SQL> DECLARE
  2    v_dev varchar2(256);
  3    v_done boolean:=false;
  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    v_fileTable(1):='D:\ORACLE\ORADATA\FULL_01JRAKVT_1_1.BAK';
  9    v_fileTable(2):='D:\ORACLE\ORADATA\FULL_02JRAL1B_1_1.BAK';
 10    v_maxPieces:=2;
 11    v_dev:=sys.dbms_backup_restore.deviceAllocate(type=>'',ident=>'t1');
 12    sys.dbms_backup_restore.restoreSetDatafile;
 13    sys.dbms_backup_restore.restoreDataFileTo(dfnumber=>1, toname=>'D:\ORACLE\ORADATA\ALEX\SYSTEM01.DBF');
 14    sys.dbms_backup_restore.restoreDataFileTo(dfnumber=>2, toname=>'D:\ORACLE\ORADATA\ALEX\UNDOTBS01.DBF');
 15    sys.dbms_backup_restore.restoreDataFileTo(dfnumber=>3, toname=>'D:\ORACLE\ORADATA\ALEX\SYSAUX01.DBF');
 16    sys.dbms_backup_restore.restoreDataFileTo(dfnumber=>4, toname=>'D:\ORACLE\ORADATA\ALEX\USERS01.DBF');
 17    FOR i IN 1..v_maxPieces LOOP
 18      sys.dbms_backup_restore.restoreBackupPiece(done=>v_done, handle=>v_fileTable(i), params=>null);
 19      IF v_done THEN
 20        GOTO all_done;
 21      END IF;
 22    END LOOP;
 23  <>
 24    sys.dbms_backup_restore.deviceDeallocate;
 25  END;
 26  /

PL/SQL 过程已成功完成。

5. 重新创建控制文件
(最好找到一个类似的环境,生成脚本后修改。)

SQL> CREATE CONTROLFILE REUSE DATABASE "ALEX" RESETLOGS  ARCHIVELOG
  2      MAXLOGFILES 5
  3      MAXLOGMEMBERS 3
  4      MAXDATAFILES 100
  5      MAXINSTANCES 1
  6      MAXLOGHISTORY 1361
  7  LOGFILE
  8    GROUP 1 'D:\Oracle\oradata\alex\redo01.log'  SIZE 100M,
  9    GROUP 2 'D:\Oracle\oradata\alex\redo02.log'  SIZE 100M,
 10    GROUP 3 'D:\Oracle\oradata\alex\redo03.log'  SIZE 100M
 11  DATAFILE
 12    'D:\Oracle\oradata\alex\system01.dbf',
 13    'D:\Oracle\oradata\alex\undotbs01.dbf',
 14    'D:\Oracle\oradata\alex\SYSAUX01.DBF',
 15    'D:\Oracle\oradata\alex\users01.dbf'
 16  CHARACTER SET ZHS16GBK
 17  ;

控制文件已创建。

6. 重新加载数据库

SQL> shutdown immediate
ORA-01109: ??????
已经卸载数据库。
ORACLE 例程已经关闭。

SQL> startup mount
ORACLE 例程已经启动。

Total System Global Area  167772160 bytes
Fixed Size                  1247900 bytes
Variable Size              79693156 bytes
Database Buffers           83886080 bytes
Redo Buffers                2945024 bytes
数据库装载完毕。

SQL> alter database flashback off;

数据库已更改。

SQL> alter database flashback on;

数据库已更改。

SQL> alter database open resetlogs;

数据库已更改。

7. 由于临时表空间数据文件已经不存在,重建临时表空间

SQL> CREATE TEMPORARY TABLESPACE temp1 TEMPFILE
  2    'D:\Oracle\oradata\alex\temp01.dbf' size 100M
  3  EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M;

表空间已创建。

SQL> alter database default temporary tablespace temp1;

数据库已更改。

SQL> drop tablespace temp;

表空间已删除。

SQL> alter tablespace temp1 rename to temp;

表空间已更改。

8. 完成恢复

补充内容:

9. 从增量备份中应用备份到数据文件

DECLARE 
  v_dev           varchar2(256);           /* 设备类型 */ 
  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; 
<> 
/* 释放设备 */ 
  sys.dbms_backup_restore.deviceDeallocate; 
END; 
/

10. 用于做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; 
<>  
  /* 释放通道  */ 
  sys.dbms_backup_restore.deviceDeallocate; 
END; 
/

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

for seq in .. loop 
    sys.dbms_backup_restore.restoreArchivedLog(thread=>1, sequence=>seq); 
  end loop
Trackback

no comment untill now

Add your comment now

切换到手机版