最近一直在忙于写shell脚本,忽略了oracle的基础的回顾,正好做了个rman的恢复,记录一下加深印象!
oracle全库备份的理想状态下在mount时做全备,这样不需要去做考虑一致性问题。仅仅是理想而已。
将数据库开为归档模式下,进行全备,脚本如下
log_file=/paic/hq/bk/restore/home/op11202/xionglang/investdw/full_backup_${ORACLE_SID}_`date '+%Y%m%d_%H%M%S'`.log
export log_file
rman target / << EOF > ${log_file} 2>&1
sql 'alter system switch logfile';
run
{
allocate channel c1 type disk;
allocate channel c2 type disk;
allocate channel c3 type disk;
allocate channel c4 type disk;
allocate channel c5 type disk;
allocate channel c6 type disk;
allocate channel c7 type disk;
allocate channel c8 type disk;
BACKUP as compressed backupset full DATABASE plus archivelog FORMAT '/paic/hq/bk/restore/home/op11202/xionglang/investdw/full_%T-%d-%u-%p' filesperset=10;
backup as copy current controlfile format '/paic/hq/bk/restore/home/op11202/xionglang/investdw/ctrl_%t-%s-%p.f';
release channel c1;
release channel c2;
release channel c3;
release channel c4;
release channel c5;
release channel c6;
release channel c7;
release channel c8;
}
EOF
echo "Backup finished at `date '+%Y%m%d_%H%M%S'`" >> ${log_file}
1.生成一份原开发/测试库的pfile
2.利用步骤1中的pfile,启动到nomount
3.rman target /
RMAN> Restore controlfile from ‘/xxxx/xxxx/*****.f’; /xxxx/xxxx/*****.f为生产dg库的controlfile的备份
RMAN> Alter database mount;
RMAN> Catalog start with ‘/xxxx/xxxx/’; 注册备份片到恢复出来的控制文件里
4.后台执行如下restore脚本。如果恢复出来了归档日志restore database之后需要recover database;
(注意incarnation相关报错)
5.恢复完成以后,shutdown实例,修改pfile里的db_name为原测试库SID 启动到nomount
6.使用create controlfile set database 命令重建控制文件
7.alter database open resetlogs;
8.添加临时文件
恢复脚本:
log_file=/paic/dev/oracle/11g/odsz11g/xionglang/xionglang/d1gccrep/restore_${ORACLE_SID}_`date '+%Y%m%d_%H%M%S'`.log
export log_file
rman target / << EOF > ${log_file} 2>&1
run
{
allocate channel c1 type disk ;
allocate channel c2 type disk ;
allocate channel c3 type disk ;
allocate channel c4 type disk ;
allocate channel c5 type disk ;
allocate channel c6 type disk ;
allocate channel c7 type disk ;
allocate channel c8 type disk ;
set newname for datafile 1 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 10 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 11 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 12 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 13 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 14 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 15 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 16 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 17 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 18 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 19 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 2 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 20 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 21 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 22 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 23 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 24 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 25 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 26 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 27 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 28 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 29 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 3 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 30 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 31 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 32 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 33 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 34 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 35 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 36 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 37 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 38 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 39 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 4 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 40 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 41 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 42 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 43 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 44 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 45 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 46 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 47 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 48 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 49 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 5 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 50 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 51 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 52 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 53 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 54 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 55 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 56 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 57 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 58 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 59 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 6 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 60 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 61 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 62 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 63 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 64 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 65 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 66 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 67 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 68 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 69 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 7 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 70 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 71 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 72 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 73 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 74 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 75 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 8 to '+DATA_10G_D1GCCREP_MDG';
set newname for datafile 9 to '+DATA_10G_D1GCCREP_MDG';
set newname for tempfile 1 to '+DATA_10G_D1GCCREP_MDG';
set newname for tempfile 2 to '+DATA_10G_D1GCCREP_MDG';
set newname for tempfile 3 to '+DATA_10G_D1GCCREP_MDG';
restore database;
switch datafile all;
switch tempfile 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;
}
EOF
echo "Restore finished at `date '+%Y%m%d_%H%M%S'`" >> ${log_file}
前面提到了恢复过程可能因为不一直导致alter database open resetlogs 起库失败。这个过程我建议使用recover database using backup controlfile utile time '2015-12-17 23:01:22' 这种指定时间去做不完全恢复,这种方式比你去应用一个个的日志恢复到一致的几率要高。因为切换日志的时候可能会有长事务并没有结束。而你指定时间点,这个时间点可能有事务,但是你可以往后面添加几秒或是十几秒基本就可以处于一致状态,然后open数据库。
查看数据库是否一致:(虽然都处于一致状态,但是你open还是有可能open是否,这样就需要向后面追加几秒时间才能正常起库。)
SQL> select to_char( max( CHECKPOINT_TIME ) ,'yyyy-mm-dd hh24:mi:ss' ) from v$datafile_header ;
TO_CHAR(MAX(CHECKPO
-------------------
2015-12-16 23:01:08
SQL> select to_char( min( CHECKPOINT_TIME ) ,'yyyy-mm-dd hh24:mi:ss' ) from v$datafile;
TO_CHAR(MIN(CHECKPO
-------------------
2015-12-16 23:01:08
SQL> select controlfile_time fromv$database;
CONTROLFILE_TIME
-------------------
2015-12-16 23:01:08
SQL> select file#,checkpoint_change# from v$datafile_header where fuzzy ='YES' ;
no rows selected
SQL> alter database open read only;
alter database open read only
*
ERROR at line 1:
ORA-16004: backup database requiresrecovery
ORA-01113: file 1 needs media recovery ifit was restored from backup, or END BACKUP if it was not
ORA-01110: data file 1:'+DATA_10G_D1GCCREP_MDG/d1gccrep/datafile/system.298.898716267'
SQL> recover database using backupcontrolfile;
ORA-00279: change 9910161874981 generatedat 12/16/2015 23:01:08 needed for thread 1
ORA-00289: suggestion : +FRA_10G_LARGE_MDG
ORA-00280: change 9910161874981 for thread1 is in sequence #3085
Specify log: {<RET>=suggested |filename | AUTO | CANCEL}
cancel
Media recovery cancelled.
另外在提一下,如果恢复不想使用set newname的方式可以通过db_file_name_convet的方式去转换文件名的路径。asm指定到dbname一级,文件系统指定到文件名前一级目录。
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_file_name_convert string +DATA_10G_T1GCCREP_MDG/t1gccrep, +DATA_10G_D1GCCREP_MDG/d1gccrep
log_file_name_convert string +DATA_10G_T1GCCREP_MDG/t1gccrep, +DATA_10G_D1GCCREP_MDG/d1gccrep, +FRA_10G_LARGE_MDG/t1gccrep, +FRA_10G_LARGE_MDG/d1gccrep
附上生成set newname的语句
select 'set newname for datafile ' || file# || ' to ''+${data_dg}'';'
from v\$datafile
union
select 'set newname for tempfile ' || file# || ' to ''+${data_dg}'';'
from v\$tempfile;
如果想要修改数据库的db_name可以通过nid的修改。需要数据库起到mount状态:
syspwd=`od -N 4 -t x4/dev/random | head -1 | awk '{print $2}'`
orapwdfile=$ORACLE_HOME/dbs/orapw${OLDSID} password=$syspwd entries=8 force=y
orapwdfile=$ORACLE_HOME/dbs/orapw${NEWSID} password=$syspwd entries=8 force=y
nidtarget=sys/$syspwd dbname=${NEWSID} >>$crt_log 2>&1 <<!
Y
!