Oracle Standby database容灾库有时因为一些原因缺少了Primary database的archivelog未应用而中断同步,如备库归档目录使用率100%,或主库未传输删除了归档等。重新搭建DATAGUARD对于较大的数据库可能是费时费力,通常可以采用增量备份的方式,最近刚好是在处理一个ogg不同步的问题时,发现OGG不报错也不抽取及时跟到standby有的归档开始,后来发现OGG是从ADG 抽取,使用的DBLOGREADER模式,在standby apply后才能抽取,而STANDBY 缺少了中间一个archivelog,,网上的类似的文档很多,步骤挺多,简单记录一下。
对于有备份归档的当然可以使用从备份恢复归档的方式解决,如果归档又无备份时可以采用下面的方法:
在备用数据库上检查当前的 SCN
-- query 1 SQL> select current_scn from v$database CURRENT_SCN ----------- 6814738497 -- query 2 SQL> select min(checkpoint_change#) from v$datafile_header where file# not in (select file# from v$datafile where enabled = 'READ ONLY'); 2 MIN(CHECKPOINT_CHANGE#) ----------------------- SQL> r select min(checkpoint_change#) from v$datafile_header where file# not in (select file# from v$datafile where enabled = 'READ ONLY') MIN(CHECKPOINT_CHANGE#) ----------------------- SQL> select checkpoint_change# from v$datafile_header; CHECKPOINT_CHANGE# ------------------ 6814738498 6814738498 6814738498 ... 22 rows selected.
Note:
最上面两个查询中最小的query 1 and query 2,本case为6814738497
在主数据库上做增量备份从上面的SCN开始
SQL> select sum(bytes)/1024/1024/1024 gb from v$datafile;
GB
----------
580.152313
RMAN>
run{
allocate channel c1 device type disk;
BACKUP as compressed backupset INCREMENTAL FROM SCN 6814738497 DATABASE FORMAT '/u01/ForStandby_%U' tag 'FORSTANDBY';
release channel c1;
}
Note:
查看库大小,如果本地磁盘空间不足,可以使用压线备份,可以节约大量的本地空间需求,但是时间相对更长。
在主数据库查看备份进度
select start_time,input_bytes,output_bytes,input_bytes_per_sec_display from v$rman_backup_job_details where status!='COMPLETED';
Note:
可以从input_bytes查看已读了数据库的多少,判断进度。
在主数据库备份standby control文件
run{
allocate channel c1 device type disk;
BACKUP CURRENT CONTROLFILE FOR STANDBY FORMAT '/u01/ForStandbyCTRL.bck';
release channel c1;
}
传输主库的以上的增量备份和standby 控制文件到备库
scp ForStandby* 192.168.xxx.xxx:/home/oracle/bak/dgbackup
在备库停止STANDBY的RECOVER进程
SQL> alter database recover managed standby database cancel;
在主库和备库检查 incarnation
RMAN> list incarnation;
Note:
应该结果是一样的
检查主库和备库的文件名
SELECT FILE#, NAME FROM V$DATAFILE;
检查主库备份后是否有增加新文件
SQL> SELECT FILE#, NAME FROM V$DATAFILE WHERE CREATION_CHANGE# > 6814738497; no rows selected
如果有文件可以单独备份还原文件
RMAN> backup datafile #, #, #, # format '/tmp/ForStandby_%U' tag 'FORSTANDBY';
run
{
set newname for datafile X to '+DISKGROUP';
set newname for datafile Y to '+DISKGROUP';
set newname for datafile Z to '+DISKGROUP';
etc.
restore datafile x,y,z,....;
}
在备库恢复standby controlfile
RMAN> SHUTDOWN IMMEDIATE ; RMAN> STARTUP NOMOUNT; RMAN> RESTORE STANDBY CONTROLFILE FROM '/tmp/ForStandbyCTRL.bck';
Note:
如果不重建或重新恢复standby控制文件,虽然数据文件头SCN已更新,但是控制文件中(v$dtafile)的scn未更新,还是会等备份前的归档,而无法继续应用。
在备库更新控制文件中数据文件名
-- 如果主库和备库路径一样,这一步可以跳过,如果主库和备库文件名不一致,因为恢复了备库的控制文件是从主库备份的,控制文件记录的文件名不是备份的实际路径,需要更名 SQL>alter database mount RMAN> catalog start with '/home/oradata/DB11GSTD/' RMAN> SWITCH DATABASE TO COPY;
Note:
我这里是因为主库是ASM,备库是本地文件系统,所以需要更名,注意要注册所有的文件路径。
在备库上注册上面的备份到standby数据库
$ rman target / RMAN> catalog start with '/home/oracle/bak/dgbackup'; using target database control file instead of recovery catalog searching for all files that match the pattern /home/oracle/bak/dgbackup List of Files Unknown to the Database ===================================== File Name: /home/oracle/bak/dgbackup/ForStandbyCTRL.bck File Name: /home/oracle/bak/dgbackup/ForStandby_kk0rh7v8_1_1 File Name: /home/oracle/bak/dgbackup/ForStandby_kl0rhbe2_1_1 Do you really want to catalog the above files (enter YES or NO)? yes cataloging files... cataloging done List of Cataloged Files ======================= File Name: /home/oracle/bak/dgbackup/ForStandbyCTRL.bck File Name: /home/oracle/bak/dgbackup/ForStandby_kk0rh7v8_1_1 File Name: /home/oracle/bak/dgbackup/ForStandby_kl0rhbe2_1_1
在本库应用增量备份
shu immediate
startup mount
RMAN>
run{
allocate channel c1 device type disk;
RECOVER DATABASE NOREDO;
release channel c1;
}
更改备库的flashback database功能(可选)
SQL> ALTER DATABASE FLASHBACK OFF; SQL> ALTER DATABASE FLASHBACK ON;
在备库清理standby 和redo logfile
SQL> begin for log_cur in ( select group# group_no from v$log ) loop execute immediate 'alter database clear logfile group '||log_cur.group_no; end loop; end; / SQL> begin for log_cur in ( select group# group_no from v$standby_log ) loop execute immediate 'alter database clear logfile group '||log_cur.group_no; end loop; end; /
Note:
如果不清理db alert会提示文件不存在,这里oracle有一点比较强的是,不用rename ,直接clear会在alert中提示无法联系ASM diskgroup,而自动改成了本地文件系统的路径。
在备库启动日志应用MRP
SQL> alter database recover managed standby database using current logfile disconnect from session;
检查主库和备库的SCN
SQL> select current_scn from v$database;
以上11G环境就基本做完了, 从18c起可以一条命令自动完成以上工作,从12c提供了一种from service的方法, 如18c或19c中,使用一个到主库的service,从备库执行:
RMAN> RECOVER STANDBY DATABASE FROM SERVICE PRM180;
RMAN> RECOVER STANDBY DATABASE FROM SERVICE primary_connect_identifier;
This command will internally keep track of standby file locations, refresh standby controlfile from primary, update the new standby controlfile with standby file names, perform incremental backup on primary, transfer the backup-pieces over network to standby and perform recovery on standby
More about:
For 11g
11g Steps to perform for Rolling Forward a Physical Standby Database using RMAN Incremental Backup. (Doc ID 836986.1)
For 12.1 and 12.2, see the following procedure:
12c How to Roll Forward a Standby Database Using Recover Database From Service (Doc ID 2850185.1)
For 18c and higher, see the following procedure:
Roll Forward Physical Standby Using RMAN Incremental Backup in Single Command (Doc ID 2431311.1)