如果數據庫在啓動時檢測到重做日誌丟失,數據庫將無法啓動。如果數據庫在運行時切換日誌文件組,檢測到下一組或者全部的重做日誌丟失,數據庫將會崩潰。所以有必要學習下Oracle重做日誌恢復的技巧。
由於磁盤介質損壞或者人爲的誤刪除文件,造成嚴重後果的事件近期時有發生。本文列舉了重做日誌丟失的數據庫恢復,但如果按照冗餘原則合理分佈日誌文件組的成員,如果工程師瞭解日誌文件的基本原理和使用原則,就完全可以避免出現下列問題。
Oracle重做日誌文件循環記錄了數據庫所有的事務。它的大小、個數和存儲位置對數據庫性能和恢復有重要影響。它一般由大小相同的幾組文件構成。我們可 以查看數據庫視圖v$logfile知道redo logfile的個數和存儲位置。對每一個Oracle數據庫都要求至少具有兩個聯機重做日誌。
每一次新的事務提交時,Oracle將該事務寫入日誌文件,但並非此時也將修改的數據塊寫回原數據文件。由於內存讀寫和磁盤I/O存在幾個數量級的效率差 別,Oracle通過減少數據文件的物理I/O讀寫來大大提高數據庫的性能;同時,又通過優先寫日誌文件來保證數據的正確性和一致性。基於這種機 制,Oracle重做日誌文件在數據庫的實例恢復和介質恢復時至關重要,是oracle數據庫最重要的物理文件之一。
故障現象
SQL> startup mount
Oracle Instance Started
Database mounted
ORA-00313: open failed for members of log group 1 of thread 1
ORA-00312: online log 1 thread 1: '/ORACLE/ORADATA/H817/REDO01.LOG'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) The system cannot find the file specified.
Oracle重做日誌恢復注意事項
以下所列舉的恢復方法,都屬於不完全恢復或者強制恢復,會丟失當前重做日誌中的事務數據。一旦操作不當,將帶來數據丟失等嚴重後果,請遵循以下幾個恢復原則:
1. 請勿在生產系統上試用。
2. 如果生產系統出現重做日誌文件丟失的故障,請勿自行操作破壞現場,應該立刻聯繫Oracle工程師。
3. 恢復成功之後,需要馬上做一次數據庫的全備份。
4. 建議重做日誌文件一定要實現鏡象在不同的磁盤上,避免這種情況的發生。
恢復方法
1. 首先檢查重做日誌文件狀態,看看報錯的日誌文件的狀態是否爲Current
SQL> select * from v$log;
SQL> select * from v$logfile;
2. 如果重做日誌文件狀態爲Inactive,我們可以直接清除該日誌文件的內容:
SQL> alter database clear logfile '/ORACLE/ORADATA/H817/REDO01.LOG';
3. 如果重做日誌文件狀態爲Current,恢復工作較爲複雜,有以下四種情況:
1)通過下面步驟,數據庫順利打開
SQL> recover database until cancel;
Type Cancel when prompted
SQL>alter database open resetlogs;
2)第一種情況的'recover database until cancel' 操作遇到ORA-01547,ORA-01194,ORA-01110錯誤,需要整個數據庫的物理備份,並根據歸檔日誌恢復到錯誤時間點,前提是數據庫是歸檔模式。
restore old backup
SQL> startup mount
SQL> recover database until cancel using backup controlfile;
SQL> alter database open resetlogs;
3)如果數據庫是非歸檔模式,只能恢復整個物理備份,然後直接打開數據庫。這種情況將丟失物理備份至故障發生前的全部數據。
4)如果數據庫是非歸檔模式,且沒有物理備份,只能通過特殊的隱含參數,允許數據庫不一致的狀況下打開數據庫。這種恢復方法是沒有辦法之後的恢復方法,將導致數據庫不一致,一般情況下不要採用。如確有需要,請在Oracle的技術人員指導下使用該方法。
關閉數據庫
SQL>shutdown immediate
在init<sid>.ora中加入如下參數 _allow_resetlogs_corruption=TRUE
重新啓動數據庫,利用until cancel恢復 SQL>recover database until cancel;
Cancel 打開數據庫 SQL>alter database open resetlogs;
數據庫被打開後,馬上執行一個全庫導出。
關閉數據庫,在init.ora中去掉_all_resetlogs_corrupt參數