首页 » ORACLE 9i-23c » 如何从oracle 备份集恢复数据库?未知DBID DBNAME, 无controlfile

如何从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

‘s Is it possible to change the character set of the database by recreating the control file?

 

 

 

打赏

,

对不起,这篇文章暂时关闭评论。