1. 程式人生 > >Oracle Database 12c RMAN全量+增量備份+歸檔日誌恢復詳解

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/

背景為今天2017年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/2017_09_22/ ,也就是我們之前backup database plus archivelog ; 與全備命令執行後所放置備份檔案的資料夾相同,然後控制檔案和SPFILE檔案被備份到了/u01/fast_recovery_area/recovery/RECOVERY/autobackup/2017_09_22/,目錄。換句話說,LEVEL=0的增量備份和全量備份的效果是一模一樣的。

我們可以看一下backupset資料夾和autobackup資料夾,觀察裡面的檔案建立日期,上午10點半那個是普通的全備,中午12點那個是LEVEL=0的增備。

上面還使用昨天(21號只做了全備)來對比。證明LEVEL=0的增備確實和全備是一樣一樣的。不同的是全備的時候還會把所有的歸檔檔案聚合起來生成一個很大的備份檔案,如backupset中最大的那個檔案,1813859328大小的這個檔案就是聚合歸檔日誌全備而來的。由於歸檔日誌記錄了每一條SQL執行的時間和順序,所以這個備份檔案會比表空間備份大很多。上午10點辦全備時的表空間大小1344995328,和剛剛的LEVEL=0的增量備份大小1351016448差不多,多出的那一塊可能是這兩個小時內新加入的資料。另外autobackup資料夾中控制檔案的兩次的備份大小都是10698752,沒有任何變化,是因為這兩個小時內資料庫的引數,表結構和數量都沒有任何變化,只是加了一些資料,所以備份出來也是一樣的。

時間已經到了2017年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/2017_09_25/目錄下,控制檔案增量備份被放到了/u01/fast_recovery_area/recovery/RECOVERY/autobackup/2017_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 '2017-09-22 11:00:00';


現在是9月25號,由於我要恢復到22號,所以Oracle自動恢復到我9月22號10點半建立的那次次全備,如果我要恢復到9月22好下午兩點,那麼Oracle就會選擇9月22號中午的那次全備,如下圖:


我把這兩個全備的日期展示一下
[root@localhost 2017_09_22]# ls -alt /u01/fast_recovery_area/recovery/RECOVERY/backupset/2017_09_22
總用量 4404200
drwxr-x---. 5 alex oinstall       4096 9月  25 10:20 ..
-rw-r-----. 1 alex oinstall 1351016448 9月  22 12:15 o1_mf_nnnd0_TAG20170922T121525_dw93lxc0_.bkp
drwxr-x---. 2 alex oinstall       4096 9月  22 12:15 .
-rw-r-----. 1 alex oinstall       4608 9月  22 10:39 o1_mf_annnn_TAG20170922T103946_dw8xzm4d_.bkp
-rw-r-----. 1 alex oinstall 1344995328 9月  22 10:39 o1_mf_nnndf_TAG20170922T103931_dw8xz3qt_.bkp
-rw-r-----. 1 alex oinstall 1813859328 9月  22 10:39 o1_mf_annnn_TAG20170922T103915_dw8xymcq_.bkp



可以看到Oracle自動選擇的功夫還是很準確的。


做完restore之後並不能直接開啟資料庫,此時表空間狀態變為OFFLINE,需要RECOVER一下然後才能執行ONLINE語句

第四步:恢復資料庫
recover database until time '2017-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.dbf
drwxr-xr-x.  2 alex oinstall      4096 9月  26 02:03 .
-rw-r-----.  1 alex oinstall  82941952 9月  25 17:06 1_23_955216458.dbf
drwx------. 33 alex oinstall      4096 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 oinstall      2048 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 oinstall      2048 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 2017_09_25]# ls -alt
總用量 62792
-rw-r-----. 1 alex oinstall 10731520 9月  25 17:06 o1_mf_s_955645585_dwkkrkl4_.bkp
drwxr-x---. 2 alex oinstall     4096 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_.bkp
drwxr-x---. 6 alex oinstall     4096 9月  25 10:21 ..

沒有產生資料檔案的備份,如下/u01/fast_recovery_area/recovery/RECOVERY/backupset/2017_09_25:
[root@localhost 2017_09_25]# ls -alt
總用量 266192
-rw-r-----. 1 alex oinstall 272572416 9月  25 10:21 o1_mf_nnnd2_TAG20170925T102119_dwjt0zhc_.bkp
drwxr-x---. 2 alex oinstall      4096 9月  25 10:21 .
drwxr-x---. 5 alex oinstall      4096 9月  25 10:20 ..


alter database open;

下面是僅恢復表空間到資料庫最後時刻。

第一步:查看錶空間的序號和狀態

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;

然後就恢復完畢,可以使用了。