如何从oracle 备份集恢复数据库?未知DBID DBNAME, 无controlfile
上周一客户咨询如果只有几个RMAN备份集文件,无任何地方得知controlfile, 如何恢复数据库?通常我们做RMAN备份会建议spfile, controlfile, datafile,archivelog一起备份,但如果没有rman备份日志,也没有备份controlfile如何恢复呢? 同时再增加一步,如果dbid 和dbname也不知道呢?
正常的流程
Step 1 – restore the spfile and start the instance
Step 2 – restore the controlfile and mount the database
Step 3 – restore the database (meaning the datafiles)
Step 4 – recover the database as far as possible (by applying archivelogs)
Step 5 – open the database in (no)resetlogs
无dbid和dbname恢复
比如我们只有几个RMAN备份文件,如xxx.bkp
找其它任何一下已mount或opend的oracle数据库环境,把1个备份集文件上传,比如放在/u02/bak目录下,尝试rman catalog会得到报错提示。如
$ rman target /
rman > catalog start with '/u02/bak' noprompt;
using target database control file instead of recovery catalog
searching for all files that match the pattern /u02/bkp
List of Files Unknown to the Database
=====================================
File Name: /u02/bkp/o1_xxx_1_.bkp
cataloging files...
no files cataloged
List of Files Which Where Not Cataloged
=======================================
File Name: /u02/bkp/o1_xxx_1_.bkp
RMAN-07518: Reason: Foreign database file DBID: 397464815 Database Name: ANBOB
有了正确备份集的DBNAME, 接下来就可以修正一下pfile的dbname 或ORACLE_SID重启实例nomount,尝试恢复控制文件
无controlfile恢复
nomount状态,可以先尝试RMAN从备份集中逐个查找一下有没有controlfile备份,如
RMAN> restore controlfile from '/u02/bkp/o1_xxx_1_.bkp'; RMAN> restore controlfile from '/u02/bkp/o1_xxx_2_.bkp'; ...
如果不存在会提示ORA-19870或ORA-19626, 如果存在会提示Finished restore,并提示恢复controlfile到output file name=$ORACLE_HOME/dbs, ,当然也有可能所有备份集中都没有控制文件备份,而此时手动SQL创建controlfile,又会校验datafile是否真实存在,而使用rman 恢复数据文件restore database需要mount,mount需要controlfile.
DBMS_BACKUP_RESTORE 包undocumented 在 Oracle9i 提供的 PL/SQL 包和类型参考以及 Oracle10g 和后续版本的 Oracle 数据库 PL/SQL 包和类型参考。 DBMS_BACKUP_ RESTORE 使得在灾难场景中无需 RMAN 即可进行恢复。 这种情况的特点是丢失所有当前控制文件,以及包含最新数据文件和归档重做日志备份记录的catalog或控制文件备份缺少或不可用。
First Available | 12.1 |
Security Model | Owned by SYS with EXECUTE granted to SYSBACKUP |
Source | {ORACLE_HOME}/rdbms/admin/dbmsbkrs.sql |
启动一个实例总比没有好。 通过这个实例,您可以访问许多东西,而无需实际拥有真正的数据库。 例如,您可以使用 dbms_backup_restore 包:该包能够在没有任何控制文件的情况下恢复数据文件。 现在对我们来说非常有用。 您可以轻松地从备份中恢复数据文件,但您必须提供数据文件编号。 几行 PL/SQL 代码可以帮助您从所有可用的备份中恢复所有数据文件。
注:nomount模式无法读取dict所有无法使用dest 查看package内容,但是可以调用。如:
SQL> desc dbms_backup_restore ERROR: ORA-01219: database or pluggable database not open: queries allowed on fixed tables or views only SQL> exec dbms_backup_restore.deviceDeallocate; PL/SQL procedure successfully completed.
然后就可以写一段plsql代码,把文件从备份信中抽出。
cd /u02/bkp/ vi extract_dbf.sql set serveroutput on declare v_dev varchar2(30) ; v_rest_ok boolean; v_df_num number := 1; v_df_max number := 30; -- you can set large more v_bck_piece varchar2(256) := '&1'; v_rest_folder varchar2(226) := '/u01/oradata/ANBOB/'; -- extract datafiles to path from restore v_rest_df varchar2(256); begin v_dev := dbms_backup_restore.deviceallocate; while v_df_num <= v_df_max loop v_rest_df := v_rest_folder||'DF_'||lpad(v_df_num,4,'0'); dbms_backup_restore.restoreSetDatafile; dbms_backup_restore.restoreDataFileTo(dfnumber=>v_df_num,toname=>v_rest_df); BEGIN dbms_backup_restore.restoreBackupPiece(done=>v_rest_ok,handle=>v_bck_piece); EXCEPTION WHEN OTHERS THEN v_rest_ok := FALSE; -- dbms_output.put_line('Datafile '||v_df_num||' is not in this piece'); END; if v_rest_ok THEN dbms_output.put_line('Datafile '||v_df_num||' is restored : '||v_rest_df); end if; v_df_num := v_df_num + 1; end loop; dbms_backup_restore.deviceDeallocate; end; / exit;
然后写段shell遍历备份集文件
$ for bkfs in `find /oracle/backup/ -name *.bkp`; do sqlplus -s / as sysdba @resto $bkfs; done;
datafile会从备份集中抽出,存放到v_rest_folder变量的路径中, 抽出的文件个数依赖于备份集中的个数, 接下来就可以手动创建controlfile了。
sqlplus / as sysdba
CREATE CONTROLFILE REUSE DATABASE "ANBOB" RESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 2073
LOGFILE
GROUP 1 '/u01/oradata/ANBOB/redo01.rdo' SIZE 100M BLOCKSIZE 512,
GROUP 2 '/u01/oradata/ANBOB/redo02.rdo' SIZE 100M BLOCKSIZE 512,
GROUP 3 '/u01/oradata/ANBOB/redo03.rdo' SIZE 100M BLOCKSIZE 512
DATAFILE
'/u01/oradata/ANBOB/DF_0001.dbf',
'/u01/oradata/ANBOB/DF_0002.dbf',
'/u01/oradata/ANBOB/DF_0003.dbf',
'/u01/oradata/ANBOB/DF_0004.dbf',
'/u01/oradata/ANBOB/DF_0005.dbf'
CHARACTER SET AL32UTF8 ;
Control file created.
接下来就可以根据上面的dbname 和controlfile 启动数据库到mount状态, RMAN注册备份集catalog start with ,restore database和restore archivelog all了, 当然要记的手动增加tempfile.如
ALTER TABLESPACE TEMP ADD TEMPFILE ‘/u01/oradata/ANBOB/temp01.dbf’;
未知字符集
在controlfile时我们看到有指定字符集, 这里有个小疑问,如果我们不知道数据库的字符集呢?创建controlfile时的字符集是数据库的字符集吗?
Note also that it’s NOT possible to change / adapt the NLS_CHARACTERSET by re-creating the control file.
The characterset specified in CREATE CONTROLFILE DATABASE … RESETLOGS ….CHARACTER SET <NLS_CHARACTERSET>; ( the result of an ALTER DATABASE BACKUP CONTROLFILE TO TRACE..) need to be the actual current NLS_CHARACTERSET of the database.
记录创建控制文件时如果指定字符集,Oracle 数据库将在控制文件中重建字符集信息。 如果随后需要对数据库进行介质恢复,则该信息将在数据库打开之前可用,以便在恢复期间可以正确解释表空间名称。仅当您使用默认字符集以外的字符集时才需要此子句,这取决于您的操作系统。 Oracle 数据库在启动过程中将当前数据库字符集打印到 $ORACLE_HOME/log 中的警报日志中。如果您正在重新创建控制文件并且使用恢复管理器进行表空间恢复,并且指定的字符集与数据字典中存储的字符集不同,则表空间恢复将不会成功。 但是,在数据库打开时,控制文件字符集将使用数据字典中的正确字符集进行更新。
您不能使用此子句修改数据库的字符集。
Reference :
Jérôme Dubar‘s blog
Vegard Kåsa‘s Is it possible to change the character set of the database by recreating the control file?
对不起,这篇文章暂时关闭评论。