本次故障背景是某客户的五套数据库由于客户误操作导致链路初始化,丢失了数据。
客户的备份情况是有做 RMAN 全备和增备以及完整的归档留存。 ( 很坑的一点,也是本次恢复的其中一套情况是他在原来正常运行的时候就将 16-20 号数据文件给 offline 了,导致没有将这 5 个文件全备出来,在 restore 的时候就没有将这 5 个数据文件 restore 出来,这倒没什么,关键是在进行 recover 的时候,使用 recover database until time "to_date('2021-9-29 15:55:00','yyyy-mm-dd hh24:mi:ss')"; 会报错 )
本次修复步骤如下 ( 针对缺少全备备份片的方法,某表空间或数据文件被 offline ,未成功备份 ) :
方法一 :
1 、将运行的数据库关闭,然后修改参数文件中记录的控制文件位置 ( 避免覆盖原有的控制文件 ) ,并新建一个数据文件存放目录,避免覆盖原有的数据文件。 ( 本次是由于数据文件在 ASM 磁盘组中,无法使用 mv 命令,本来只要 mv 原文件夹就行,然后只能 mkdir 一个 newxxxx 出来存放 restore 的数据文件 )
2 、修改完参数后,起到 nomount 状态,然后使用控制文件备份片恢复控制文件
rman target / startup nomount; restore controlfile from '/rmanbackup/databak/ctl_xxxx_j00a5f2m_1_1';
3 、起到 mount 状态,然后注册全备和增备的备份片以及归档备份片。
alter database mount; catalog start with '/rmanbackup/databak/z/'; catalog start with '/rmanbackup/archbak/z/';
4 、使用脚本开始 restore 数据文件
拼接 set newname 语句
select 'set newname for datafile '||FILE#||' to '||''''||'+DATAC1/newjsjf/'||substr(name,instr(name,'/',-1)+1)||''''||';' from v$datafile;
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=/u01/app/oracle/product/19.0.0.0/dbhome_1
export ORACLE_SID=jsjf2
rman target / log=/tmp/rman.log << EOF
run{
allocate channel c1 device type disk;
allocate channel c2 device type disk;
allocate channel c3 device type disk;
allocate channel c4 device type disk;
allocate channel c5 device type disk;
allocate channel c6 device type disk;
allocate channel c7 device type disk;
allocate channel c8 device type disk;
set until time "to_date('2021-9-29 15:55:00','yyyy-mm-dd hh24:mi:ss')";
set newname for datafile 1 to '+DATAC1/newxxxx/system01.dbf';
set newname for datafile 2 to '+DATAC1/newxxxx/sysaux01.dbf';
set newname for datafile 3 to '+DATAC1/newxxxx/undotbs01.dbf';
…
set newname for datafile 56 to '+DATAC1/newxxxx/gj05.dbf';
restore database;
switch datafile all;
recover database;
release channel c1;
release channel c2;
release channel c3;
release channel c4;
release channel c5;
release channel c6;
release channel c7;
release channel c8;
}
exit
EOF
5 、resetlogs 打开数据库即可
sqlplus / as sysdba
alter database open resetlogs;
方法二:
跳过缺失 数据文件的 表空间的方式去 recover database 。
可以在 RMAN 命令行里用 show all 命令查看表空间名 。
前三步骤都一样,起到 mount 后,开始 restore 和 recover 。
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=/u01/app/oracle/product/19.0.0.0/dbhome_1
export ORACLE_SID=jsjf2
rman target / log=/tmp/rman.log << EOF
run{
allocate channel c1 device type disk;
allocate channel c2 device type disk;
allocate channel c3 device type disk;
allocate channel c4 device type disk;
allocate channel c5 device type disk;
allocate channel c6 device type disk;
allocate channel c7 device type disk;
allocate channel c8 device type disk;
set newname for datafile 1 to '+DATAC1/newxxxx/system01.dbf';
set newname for datafile 2 to '+DATAC1/newxxxx/sysaux01.dbf';
set newname for datafile 3 to '+DATAC1/newxxxx/undotbs01.dbf';
...
set newname for datafile 56 to '+DATAC1/newxxxx/gj05.dbf';
restore database;
switch datafile all;
release channel c1;
release channel c2;
release channel c3;
release channel c4;
release channel c5;
release channel c6;
release channel c7;
release channel c8;
}
exit
EOF
然后再 recover database:
rman target /
recover database until time "to_date('2021-9-29 15:55:00','yyyy-mm-dd hh24:mi:ss')" skip forever tablespace xxxx;
