200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Oracle Database 12c RMAN全量+增量备份+归档日志恢复详解

Oracle Database 12c RMAN全量+增量备份+归档日志恢复详解

时间:2024-02-05 12:59:49

相关推荐

Oracle Database 12c RMAN全量+增量备份+归档日志恢复详解

Oracle可以非常方便的把数据库恢复到具体某个时间的状态,而且还支持全备和多级增备,备份无需停止应用服务。比起DB2需要手动逐级恢复增量备份和归档日志,RMAN是非常简单好用的数据库商业解决方案。

下面是我的环境:

操作系统:CentOS 6.7

Oracle版本:Oracle Database 12c Release 2(12.2.0.1.0)

数据库Sid:recovery

数据库归档:开启

数据库归档位置:/home/alex/db_backup

fast_recovery_area:开启

fast_recovery_area位置:/u01/fast_recovery_area/

背景为今天9月22日,昨天做了一次全备,数据库是20号建立的,21号执行了一些建表语句。

进入RMAN的命令是

su - 数据库用户名rman target sys/管理员密码@数据库ip地址:端口/数据库实例名

昨天在建表完成后使用RMAN执行的全备+归档日志全备命令是:

backup database plus archivelog ;

今天也执行这样一跳命令进行备份,下面是今天备份前和备份后各个目录内容的变化。

首先是表空间目录

【备份前】

【备份后】

可以发现表空间目录除了修改日期变了之外其他没什么变化。

再来看一下快速恢复区:/u01/fast_backup_area/recovery/RECOVERY/backupset

【备份前】

【备份后】

可以看到每一次执行全备就会多出一个文件夹,文件夹的名字是备份时的日期。

再来看看本分完之后这个文件夹里面有什么东西

会发现里面有两个1G多的文件,这应该就是数据库全备完的东西了,具体几个文件里面存的是什么下文会说。

在看看sqlplus中archive log list中返回的内容

【备份前】

【备份后】

当前的归档序列从12一下子升到14

在看看rman的list backup;命令返回的项目

【备份前】

可以看到,上一次备份有两个1G一上的大文件,一个是备份的表空间,一个是备份的归档。其中归档是备份的序号1到序号8

【备份后】

可以看出本次备份也备份了一个表空间和一个归档日志的集合,不同的是这次归档日志从序号1-12,看一下备份前后产生了哪些新的归档

从文件的创建日期可以看出,序号12和序号13都是在备份的时刻生成的,其中归档13只有很小的一点,才2K,而归档12也没有满,只有100M左右就进入归档13了。归档11是凌晨执行的而且已经快满了。也就是说在执行备份的瞬间会终止掉当前的归档并新开一个归档,然后过一小会这个新开的归档也被终止,又新开一个归档进行正常使用。这就是为什么当前归档文件从12一下子跳到了14的原因。本次全备只会收录全备前一刻产生的归档文件,也就是只到12。13,14均不会被备份。

下面执行一个LEVEL=0的数据库备份,也就是全备,执行语句是

backup incremental level =0 database;

下图为执行效果

可以看出,执行这条语句会对表空间做一次全备,并且把表空间数据备份到了/u01/fast_recovery_area/recovery/RECOVERY/backupset/_09_22/ ,也就是我们之前backup database plus archivelog ; 与全备命令执行后所放置备份文件的文件夹相同,然后控制文件和SPFILE文件被备份到了/u01/fast_recovery_area/recovery/RECOVERY/autobackup/_09_22/,目录。换句话说,LEVEL=0的增量备份和全量备份的效果是一模一样的。

我们可以看一下backupset文件夹和autobackup文件夹,观察里面的文件创建日期,上午10点半那个是普通的全备,中午12点那个是LEVEL=0的增备。

上面还使用昨天(21号只做了全备)来对比。证明LEVEL=0的增备确实和全备是一样一样的。不同的是全备的时候还会把所有的归档文件聚合起来生成一个很大的备份文件,如backupset中最大的那个文件,1813859328大小的这个文件就是聚合归档日志全备而来的。由于归档日志记录了每一条SQL执行的时间和顺序,所以这个备份文件会比表空间备份大很多。上午10点办全备时的表空间大小1344995328,和刚刚的LEVEL=0的增量备份大小1351016448差不多,多出的那一块可能是这两个小时内新加入的数据。另外autobackup文件夹中控制文件的两次的备份大小都是10698752,没有任何变化,是因为这两个小时内数据库的参数,表结构和数量都没有任何变化,只是加了一些数据,所以备份出来也是一样的。

时间已经到了9月25号,距离上一次LEVEL=0的全备已经过去了3天,现在开始做一次LEVEL=2的增量备份

为什么要做LEVEL=2而不是1呢,下面列举一个一般的应用情况:

备份策略典型案例:

每半年做一个数据库的全备份(包括所有的数据和只读表空间)

每一个月做一次零级备份(不包含只读表空间)

每个星期做一次一级备份

每天做一次二级备份

首先要了解Oracle增量备份的两个模式:

差异增量备份:n 级备份,备份自最近n 级或更低级别备份以来更改过的所有块。

累计增量备份:n 级备份,它包含自上次n-1 级或更低级别备份以来更改过的所有块。累计增量备份使用cumulative关键字,如:BACKUP INCREMENTAL level 2cumulative DATABASE;

详细点说就是,在差异增量备份下,如果每天晚上24:00进行一次2级(全部都是2级或者全部都是1级)增量备份,那么每次备份出来的就是当天产生的数据库变动记录。如果你这一周每天都进行2级备份,然后突然发现周三晚上备份的找不到了,那么在周六数据库崩溃了,你想恢复到周五晚上的状态,就不可能了。顶多恢复到周二晚上的状态。因为这种情况下,一般会先恢复最近的0级备份作为基础数据库,再恢复最近的1级备份作为增量,然后逐个恢复2级备份的增量。也就是你先恢复到上次的全备,然后一天一天的进行恢复,先恢复到周一晚,再恢复到周二晚,当你想恢复到周三晚的时候,发现数据库文件丢失了,那你就恢复不到周三晚,周四周五的备份也就没用了。

全部使用某级备份的坏处就是,如果某天出现了断档,那么这一天之后备份的数据就全都没用了。而如果在2级备份中穿插几个1级备份,比如每3次二级备份之后就换成一次1级备份,那么这个一级备份会比2级备份所占空间要大,它会备份自上次一级备份(没有1级就找0级)之后做的所有修改。比如周日做了一次1级备份,周一2级,周二2级,周三2级,周四1级,那么周四的备份不光含有周四一天做的修改,还包括周一周二周三三天做的全部修改,这样的话周一周二周三任意一天的备份丢失周六一样能恢复到周五晚上的状态。所以在高级级备份中定期穿插低级备份,可以有效防止断档产生的无法恢复的问题,而且比全备又节省了空间。

而累计增量备份是什么意思呢,如果还是按照上面说的,每天都做2级备份(或者每天都1级)。假设周日晚做了一次全备,那么周一备份的是周一所做的修改,周二不光有周二一天的修改,还包括周一的修改,同理周三记录了周三周二周一三天的修改。因为虽然每天都是2级,但是备份起始日期是从上次一级开始的。所以名副其实的叫做积聚备份,但是大小当然要比差异增量备份要大的多,但是安全性也更好。如果周六数据库崩了,那么可以直接用上周日的全备和周五的增量备份两个文件就可以恢复到周五晚。周一周二周三周四全都丢了也没事。

想要达到空间和安全性的平衡,当然是在差异增量备份模式下,每隔几天执行一次低级备份最好。

比如说每天中午执行一次4级备份,每天晚上24:00执行一次3级备份,每周三执行一次2级备份,每周日执行一次1级备份,每月执行一次0级全备。这样可以以半天为单位进行数据库恢复。

下面执行一次二级备份看看效果

RMAN> backup incremental level = 2 database;

可以看到,表空间增量备份被放到了/u01/fast_recovery_area/recovery/RECOVERY/backupset/_09_25/目录下,控制文件增量备份被放到了/u01/fast_recovery_area/recovery/RECOVERY/autobackup/_09_25/目录下。由于之前只做过0级备份没做过1级备份,所以这次增量是从上次的0级备份依赖发生的全部修改。

然后执行

RMAN >list backup;

查看刚刚备份的文件,能看到就是多出来上面那两个

大小为259.94M,比全备要小的多。

下面来介绍一下如何恢复数据库,恢复数据库一般采用两种方式:全库恢复和单个表空间的恢复。

其中全库恢复需要停掉当前的数据库实例,这样做存在很大的风险,一不小心就启动不了实例了。所以全库恢复一定要考虑清楚。而表空间恢复只是把当前用户的表空间离线掉,然后只恢复这个表空间就可以了。比较安全不容易玩瘫。但是无论哪一种都推荐在恢复之前做一次全备防止以外发生。

恢复数据库一般处于两种目的:一个是数据库崩溃了,磁盘坏掉了,硬件损坏导致道歉表空间损坏。

第二种是数据库出现了误操作,误删了数据,或者遭到黑客攻击丢失了重要数据的时候,需要恢复到之前某个时间点。

无论是哪种目的,恢复起来都是大同小异,只是恢复目的日期不同。都是找到离目的日期最近的一次全备,然后应用增量备份或者archive log。只要的数据库开启了日志归档功能,又养成了良好的全备和增备的习惯,那么一般问题不大。

下面全部是在RMAN环境下操作

首先介绍一下全库恢复,所谓的全库恢复其实就是所有的表空间恢复。

第一步:停止数据库

shutdown immediate;

第二步:打开数据库,这一步很可能就打不开了,所以要好好祈祷。如果出现了“ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务”错误,那么就静态绑定listener.ora文件

startup mount

第三步:还原数据库,此时Oracle会寻找离当前最近的一次全备和增备,然后根据这些备份回滚到最近的备份。不过在这之前,要先设置临时回话的时间格式,退出RMAN失效

sql "alter session set nls_date_format=''yyyy-mm-dd hh24:mi:ss''";

restore database until time '-09-22 11:00:00';

现在是9月25号,由于我要恢复到22号,所以Oracle自动恢复到我9月22号10点半建立的那次次全备,如果我要恢复到9月22好下午两点,那么Oracle就会选择9月22号中午的那次全备,如下图:

我把这两个全备的日期展示一下

[root@localhost _09_22]# ls -alt /u01/fast_recovery_area/recovery/RECOVERY/backupset/_09_22总用量 4404200drwxr-x---. 5 alex oinstall 4096 9月 25 10:20 ..-rw-r-----. 1 alex oinstall 1351016448 9月 22 12:15 o1_mf_nnnd0_TAG0922T121525_dw93lxc0_.bkpdrwxr-x---. 2 alex oinstall 4096 9月 22 12:15 .-rw-r-----. 1 alex oinstall 4608 9月 22 10:39 o1_mf_annnn_TAG0922T103946_dw8xzm4d_.bkp-rw-r-----. 1 alex oinstall 1344995328 9月 22 10:39 o1_mf_nnndf_TAG0922T103931_dw8xz3qt_.bkp-rw-r-----. 1 alex oinstall 1813859328 9月 22 10:39 o1_mf_annnn_TAG0922T103915_dw8xymcq_.bkp

可以看到Oracle自动选择的功夫还是很准确的。

做完restore之后并不能直接开启数据库,此时表空间状态变为OFFLINE,需要RECOVER一下然后才能执行ONLINE语句

第四步:恢复数据库

recover database until time '-09-22 11:00:00';

此时数据库会寻找全备日期之后的归档日志文件,并逐渐恢复到你设定的时间,如果后面不加时间限制,那么就根据归档日志恢复到当前时间。前提是你的数据库开启了归档模式。

第五步:重新指定日志计划并启动数据库

由于我们把数据库回滚到了一个之前的时间。相当于在以前的数据库历史上新建了一个分支,我们之前的归档日志序号到了22,而这次只恢复了13和14,那么15到22的日志在这个新分支上都失去作用了,所以我们要建立新的日志计划,记录新的从14以后的日志。

sql 'alter database open resetlogs';

执行这一条命令之后,我们的归档日志会发生巨大的变化,序号重新从1开始计算,并且在上一波日志的最后产生一个新的归档,序列号是最大的,如下

[root@localhost db_backup]# ls -alt总用量 3578628-rw-r-----. 1 alex oinstall 175544320 9月 26 02:03 1_1_955645578.dbfdrwxr-xr-x. 2 alex oinstall4096 9月 26 02:03 .-rw-r-----. 1 alex oinstall 82941952 9月 25 17:06 1_23_955216458.dbfdrwx------. 33 alex oinstall4096 9月 25 14:47 ..-rw-r-----. 1 alex oinstall 176169472 9月 25 09:21 1_22_955216458.dbf-rw-r-----. 1 alex oinstall 175421440 9月 24 19:59 1_21_955216458.dbf-rw-r-----. 1 alex oinstall 177026048 9月 24 14:29 1_20_955216458.dbf-rw-r-----. 1 alex oinstall 175378432 9月 24 09:07 1_19_955216458.dbf-rw-r-----. 1 alex oinstall 179865088 9月 24 00:47 1_18_955216458.dbf-rw-r-----. 1 alex oinstall 179706368 9月 23 19:16 1_17_955216458.dbf-rw-r-----. 1 alex oinstall 175430144 9月 23 14:04 1_16_955216458.dbf-rw-r-----. 1 alex oinstall 176826880 9月 23 08:25 1_15_955216458.dbf-rw-r-----. 1 alex oinstall 176290304 9月 23 00:24 1_14_955216458.dbf-rw-r-----. 1 alex oinstall2048 9月 22 10:39 1_13_955216458.dbf-rw-r-----. 1 alex oinstall 106654208 9月 22 10:39 1_12_955216458.dbf-rw-r-----. 1 alex oinstall 177561600 9月 22 00:01 1_11_955216458.dbf-rw-r-----. 1 alex oinstall 178752000 9月 21 22:00 1_10_955216458.dbf-rw-r-----. 1 alex oinstall2048 9月 21 09:08 1_9_955216458.dbf-rw-r-----. 1 alex oinstall 94164480 9月 21 09:07 1_8_955216458.dbf-rw-r-----. 1 alex oinstall 176815616 9月 21 08:46 1_7_955216458.dbf-rw-r-----. 1 alex oinstall 175357440 9月 21 08:35 1_6_955216458.dbf-rw-r-----. 1 alex oinstall 176549376 9月 21 08:29 1_5_955216458.dbf-rw-r-----. 1 alex oinstall 175982592 9月 21 08:26 1_4_955216458.dbf-rw-r-----. 1 alex oinstall 177179136 9月 21 08:23 1_3_955216458.dbf-rw-r-----. 1 alex oinstall 178763264 9月 21 00:18 1_2_955216458.dbf-rw-r-----. 1 alex oinstall 196074496 9月 20 22:00 1_1_955216458.dbf

序号23的归档日志才80M,没有满,而且是17:06进行数据库恢复时产生的,然后在第二天也就是26号,能看到归档日志的序号又变成了1。相当于之前的归档日志都失效了。

另外恢复操作还会产生一个控制文件的备份,如下,在/u01/fast_recovery_area/recovery/RECOVERY/autobackup 多了一个17:06的文件。但是不会生成数据文件的备份。

(下面其他时间的备份文件是由于单个表空间恢复至当前时间而生成的,与本案例无关)同样你也可以在RMAN的list backup中看到这些控制文件的全备。

[root@localhost _09_25]# ls -alt总用量 62792-rw-r-----. 1 alex oinstall 10731520 9月 25 17:06 o1_mf_s_955645585_dwkkrkl4_.bkpdrwxr-x---. 2 alex oinstall4096 9月 25 17:06 .-rw-r-----. 1 alex oinstall 10731520 9月 25 15:21 o1_mf_s_955639269_dwkcm53r_.bkp-rw-r-----. 1 alex oinstall 10731520 9月 25 14:56 o1_mf_s_955637766_dwkb4650_.bkp-rw-r-----. 1 alex oinstall 10698752 9月 25 14:46 o1_mf_s_955637164_dwk9kdxy_.bkp-rw-r-----. 1 alex oinstall 10698752 9月 25 14:26 o1_mf_s_955635962_dwk8ct6p_.bkp-rw-r-----. 1 alex oinstall 10698752 9月 25 10:21 o1_mf_s_955621294_dwjt1h0m_.bkpdrwxr-x---. 6 alex oinstall4096 9月 25 10:21 ..

没有产生数据文件的备份,如下/u01/fast_recovery_area/recovery/RECOVERY/backupset/_09_25:

[root@localhost _09_25]# ls -alt总用量 266192-rw-r-----. 1 alex oinstall 272572416 9月 25 10:21 o1_mf_nnnd2_TAG0925T102119_dwjt0zhc_.bkpdrwxr-x---. 2 alex oinstall4096 9月 25 10:21 .drwxr-x---. 5 alex oinstall4096 9月 25 10:20 ..

alter database open;

以上操作,可以在出现事故的时候恢复一次,比如现在时晚上10点,执行了误删操作之后可以恢复到9点的数据,但是执行过一次恢复之后,想要再恢复至8点,那么restore的时候就会报错:

RMAN-00571: ===========================================================RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============RMAN-00571: ===========================================================RMAN-03002: failure of set command at 06/26/ 23:11:16RMAN-7: UNTIL TIME or RECOVERY WINDOW is before RESETLOGS time

因为如果第一次恢复到了晚上9点,那么相当于重新做了一个数据库分支,此分支和恢复前的库已经没有线性关系,所以在新的分支上不能直接恢复到老分支的时刻,正如我们恢复后执行的alter database open resetlogs,因为retlogs了,所以原有的归档日志都无法使用了。但是这不意味这以前的归档日志,包括全备和增备文件都消失了,它们还是在的,我们理论上仍可以使用旧有文件进行恢复,首先需要切换分支。

下面是查询分支,然后停掉数据库至mount,然后切换分支,重新restore,revocer的语句

RMAN> list incarnation; using target database control file instead of recovery catalogList of Database IncarnationsDB Key Inc Key DB Name DB ID STATUS Reset SCN Reset Time------- ------- -------- ---------------- --- ---------- ----------1 1 CREDIT 4013017413 PARENT 121-MAY-192 2 CREDIT 4013017413 CURRENT 35226316 26-APR-20RMAN> shutdown immediate;database closeddatabase dismountedOracle instance shut downRMAN> startup mount;connected to target database (not started)Oracle instance starteddatabase mountedTotal System Global Area 2516582400 bytesFixed Size 8623832 bytesVariable Size889194792 bytesDatabase Buffers 1610612736 bytesRedo Buffers 8151040 bytesRMAN> RESET DATABASE TO INCARNATION 1;database reset to incarnation 1RMAN> sql "alter session set nls_date_format=''yyyy-mm-dd hh24:mi:ss''";sql statement: alter session set nls_date_format=''yyyy-mm-dd hh24:mi:ss''RMAN> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') time from dual;TIME--------------------04-26 23:18:48RMAN> restore database until time '-04-26 20:00:00';Starting restore at 26-APR-20allocated channel: ORA_DISK_1channel ORA_DISK_1: SID=781 device type=DISKchannel ORA_DISK_1: starting datafile backup set restorechannel ORA_DISK_1: specifying datafile(s) to restore from backup setchannel ORA_DISK_1: restoring datafile 00001 to /tableSpace/credit/system01.dbfchannel ORA_DISK_1: restoring datafile 00002 to /tableSpace/credit/sysaux01.dbfchannel ORA_DISK_1: restoring datafile 00003 to /tableSpace/credit/undotbs01.dbfchannel ORA_DISK_1: restoring datafile 00004 to /tableSpace/credit/bankwf01.dbfchannel ORA_DISK_1: restoring datafile 00005 to /tableSpace/credit/users01.dbfchannel ORA_DISK_1: reading from backup piece /backups/backup/orcl_full_8tuuiftb_1_1channel ORA_DISK_1: piece handle=/backups/backup/orcl_full_8tuuiftb_1_1 tag=TAG2025T224603channel ORA_DISK_1: restored backup piece 1channel ORA_DISK_1: restore complete, elapsed time: 00:00:35Finished restore at 26-APR-20RMAN> recover database until time '-04-26 20:00:00';Starting recover at 26-APR-20using channel ORA_DISK_1starting media recoveryarchived log for thread 1 with sequence 360 is already on disk as file /tableSpace/fast_recovery_area/credit/CREDIT/archivelog/_04_25/o1_mf_1_360_hb8mb78b_.arcarchived log for thread 1 with sequence 361 is already on disk as file /tableSpace/fast_recovery_area/credit/CREDIT/archivelog/_04_26/o1_mf_1_361_hb9msf57_.arcarchived log for thread 1 with sequence 362 is already on disk as file /tableSpace/fast_recovery_area/credit/CREDIT/archivelog/_04_26/o1_mf_1_362_hbbr2fjg_.arcarchived log for thread 1 with sequence 363 is already on disk as file /tableSpace/fast_recovery_area/credit/CREDIT/archivelog/_04_26/o1_mf_1_363_hbc1gzo0_.arcarchived log file name=/tableSpace/fast_recovery_area/credit/CREDIT/archivelog/_04_25/o1_mf_1_360_hb8mb78b_.arc thread=1 sequence=360archived log file name=/tableSpace/fast_recovery_area/credit/CREDIT/archivelog/_04_26/o1_mf_1_361_hb9msf57_.arc thread=1 sequence=361archived log file name=/tableSpace/fast_recovery_area/credit/CREDIT/archivelog/_04_26/o1_mf_1_362_hbbr2fjg_.arc thread=1 sequence=362archived log file name=/tableSpace/fast_recovery_area/credit/CREDIT/archivelog/_04_26/o1_mf_1_363_hbc1gzo0_.arc thread=1 sequence=363media recovery complete, elapsed time: 00:00:39Finished recover at 26-APR-20RMAN> sql 'alter database open resetlogs';sql statement: alter database open resetlogs

下面是仅恢复表空间到数据库最后时刻。

第一步:查看表空间的序号和状态

select name,status,file# from v$datafile;

可以看到我们所需要的表空间序号为5,当前是ONLINE状态

第二步:下线表空间

找到数据库用户的表空间序号(我这里是5),然后执行

alter database datafile 5 offline;

下线之后,表空间从ONLINE状态变成RECOVER状态

然后执行数据库回滚,此时Oracle会自动寻找你设置的时间离的最近的一次全备和增备时间,然后自动把表回滚到最近一次备份的时间。

restore datafile 5 ;

做完restore之后并不能直接开启数据库,需要执行RECOVER指令,但是注意对单个数据库进行恢复,restore可以恢复到某个全备的阶段,但是recover后面加until time是没有用的,加了跟没加一样,会直接恢复到当前最后一个归档日志。

recover datafile 5;

此时表空间还是OFFLINE,需要打开它,由于该次恢复最后的结果和数据库崩溃之前完全一样,可以按照原来的归档日志继续往下写,所以不需要执行alter database open resetlogs了

alter database datafile 5 online;

然后就恢复完毕,可以使用了。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。