1. 程式人生 > 其它 >恢復控制檔案避免使用resetlogs選項 (r10筆記第12天)

恢復控制檔案避免使用resetlogs選項 (r10筆記第12天)

在搭建Data Guard的時候,我們可以直接從主庫生成一個備庫控制檔案,或者拷貝一個備庫的控制檔案即可,後續的工作就交給Data Guard來自動恢復完成了,尤其是使用rman備份恢復的時候,使用recover database是一氣呵成,我們無須理會其中更多的細節,當然實際上Oracle已經幫我們處理好了。 我們都知道控制檔案的備份有兩種方式,一種是映象,一種是trace。映象備份方式類似alter database backup controlfile to 'xxxxx'這樣的形式,而trace備份則類似於alter database backup controlfile to trace這樣的形式。 從不少實際的操作中,我發現映象的恢復方式會帶來不少的困擾,如果是一個新人來做控制檔案的恢復,可能會栽入不少坑裡。最後一番折騰可能會帶來一種直觀的感覺就是控制檔案實在太重要了,如果要恢復,操作複雜度和不完全恢復差不多。而且最讓人糾結的是,折騰一番之後,還要resetlogs的方式open資料庫,我不喜歡這種恢復方式,明明完全恢復,為什麼需要這麼多的彎路。我們可能在rman中也設定了autobackup,在11g中其實是有隱含引數來控制延遲建立,預設是5分鐘。可見控制檔案還是給很多人帶來了太多困擾。 那麼怎麼恢復控制檔案比較好呢。怎麼使得控制檔案的恢復無需resetlogs呢。其實實現起來很簡單。 我們先來看看糾結的映象恢復方式。首先是備份。 sys@OCP11G> alter database backup controlfile to '/home/ora11g/ctl.bak' reuse; Database altered. [ora11g@jeanron100 ~]$ sqlplus / as sysdba sys@OCP11G> select *from v$controlfile; STATUS ------- NAME ------------------------------------------------ IS_ BLOCK_SIZE FILE_SIZE_BLKS --- ---------- -------------- /u01/app/ora11g/oradata/ocp11g/control01.ctl NO 16384 614 /u01/app/ora11g/flash_recovery_area/ocp11g/control02.ctl NO 16384 614 2 rows selected.

我們手工刪除控制檔案 [ora11g@jeanron100 ~]$ rm /u01/app/ora11g/oradata/ocp11g/control01.ctl [ora11g@jeanron100 ~]$ rm /u01/app/ora11g/flash_recovery_area/ocp11g/control02.ctl 這個時候停庫會報錯,所以只能是abort方式的斷電重啟。 sys@OCP11G> shutdown immediate ORA-00210: cannot open the specified control file ORA-00202: control file: '/u01/app/ora11g/oradata/ocp11g/control01.ctl' ORA-27041: unable to open file Linux-x86_64 Error: 2: No such file or directory Additional information: 3 sys@OCP11G> shutdown abort ORACLE instance shut down.
然後重啟啟動到nomount sys@OCP11G> startup nomount 然後開始還原控制檔案。 [ora11g@jeanron100 ~]$ cp /home/ora11g/ctl.bak /u01/app/ora11g/oradata/ocp11g/control01.ctl [ora11g@jeanron100 ~]$ cp /home/ora11g/ctl.bak /u01/app/ora11g/flash_recovery_area/ocp11g/control02.ctl 接著mount就沒有問題了。 idle> alter database mount; Database altered. 當然在啟庫的時候肯定會有下面的提示資訊,需要設定為resetlogs模式。 idle> alter database open; alter database open * ERROR at line 1: ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
當然我們嘗試resetlogs,結果還是會有一連串的ORA錯誤丟擲來。而在嘗試recover的時候會提示recover using backup controlfile idle> recover database; ORA-00283: recovery session canceled due to errors ORA-01610: recovery using the BACKUP CONTROLFILE option must be done 這個時候會折騰幾次,因為歸檔中的資料變化都應用完了,資料庫不知道該從哪個redo中恢復,這個就給問題的解決鋪下了障礙。我們需要帶著一絲的運氣逐個輸入redo的路徑,快則一次搞定,滿則需要多輪驗證。 idle> recover database using backup controlfile; ORA-00279: change 1178971 generated at 09/04/2016 02:03:43 needed for thread 1 ORA-00289: suggestion : /u01/app/ora11g/flash_recovery_area/OCP11G/archivelog/2016_09_04/o1_mf_1_25_%u_.arc ORA-00280: change 1178971 for thread 1 is in sequence #25 Specify log: {<RET>=suggested | filename | AUTO | CANCEL} 當然費了一番周折還是提示要resetlogs idle> alter database open; alter database open * ERROR at line 1: ORA-01589: must use RESETLOGS or NORESETLOGS option for database open 而改進的方式就是使用trace的方式,我們在這個基礎上繼續補充,就不需要resetlogs了。 因為已經恢復了控制檔案,但是似乎控制檔案的SCN已經比資料檔案頭部要舊了。不過整體來看,資料檔案的資訊沒有變化,只有最後的SCN的部分有一些差別,那麼我們就可以使用trace的方式來彌補。 idle> startup nomount idle> CREATE CONTROLFILE REUSE DATABASE "OCP11G" NORESETLOGS ARCHIVELOG 2 MAXLOGFILES 16 3 MAXLOGMEMBERS 3 4 MAXDATAFILES 100 5 MAXINSTANCES 8 6 MAXLOGHISTORY 292 7 LOGFILE 8 GROUP 1 '/u01/app/ora11g/oradata/ocp11g/redo01.log' SIZE 50M BLOCKSIZE 512, 9 GROUP 2 '/u01/app/ora11g/oradata/ocp11g/redo02.log' SIZE 50M BLOCKSIZE 512, 10 GROUP 3 '/u01/app/ora11g/oradata/ocp11g/redo03.log' SIZE 50M BLOCKSIZE 512 11 -- STANDBY LOGFILE 12 DATAFILE 13 '/u01/app/ora11g/oradata/ocp11g/system01.dbf', 14 '/u01/app/ora11g/oradata/ocp11g/sysaux01.dbf', 15 '/u01/app/ora11g/oradata/ocp11g/undotbs01.dbf', 16 '/u01/app/ora11g/oradata/ocp11g/users01.dbf', 17 '/u01/app/ora11g/oradata/ocp11g/testdata01.dbf', 18 '/u01/app/ora11g/oradata/ocp11g/testdata02.dbf' 19 CHARACTER SET UTF8 20 ; idle> recover database ; Media recovery complete. idle> alter database open; Database altered. 這個過程中直接alter database open也沒有問題,問題引刃而解。 這個修復的過程讓我想起來MySQL中的GTID,就是一個全域性的標記位。使得搭建slave的時候更加省心,大多數情況其實我們也不需要知道更細節的 SCN,交給MySQL自己去判斷就好。對於Oracle的恢復來說也是如此,我們可以藉助Oracle提供的完善的後臺服務來完成這個恢復工作,而無需 使用resetlogs,何樂而不為。