Oracle資料庫的非常規恢復

aluocp發表於2009-09-18

一、損壞聯機日誌的恢復方法

1.1 損壞非當前聯機日誌
大家都清楚,聯機日誌分為當前聯機日誌和非當前聯機日誌,非當前聯機日誌的損壞是比較簡單的,一般透過clear命令就可以解決問題。
1、啟動資料庫,遇到ORA-00312 or ORA-00313錯誤,如
ORA-00313: open failed for members of log group 1 of thread 1
ORA-00312: online log 1 thread 1: 'D:ORACLEORADATATESTREDO01.LOG'
從這裡我們知道日誌組1的資料檔案損壞了
從報警檔案可以看到更詳細的資訊
2、檢視V$log檢視
SQL> select group#,sequence#,archived,status from v$log;

GROUP# SEQUENCE# ARCHIVED STATUS
---------- ---------- -------- ----------------
1 1 YES INACTIVE
2 2 YES INACTIVE
3 3 NO CURRENT
可以知道,該組是非當前狀態,而且已經歸檔。
3、用CLEAR命令重建該日誌檔案
SQL>alter database clear logfile group 1;
如果是該日誌組還沒有歸檔,則需要用
SQL>alter database clear unarchived logfile group 1;
4、開啟資料庫,重新備份資料庫
SQL>alter database open;
說明:
1、如果損壞的是非當前的聯機日誌檔案,一般只需要clear就可以重建該日誌檔案,但是如果該資料庫處於歸檔狀態但該日誌還沒有歸檔,就需要強行clear。
2、建議clear,特別是強行clear後作一次資料庫的全備份。
3、此方法適用於歸檔與非歸檔資料庫

[@more@]

1.2 損壞當前聯機日誌
歸檔模式下當前日誌的損壞有兩種情況,
一、是資料庫是正常關閉,日誌檔案中沒有未決的事務需要例項恢復,當前日誌組的損壞就可以直接用alter database clear unarchived logfile group n來重建。
二、是日誌組中有活動的事務,資料庫需要媒體恢復,日誌組需要用來同步,有兩種補救辦法
A. 最好的辦法就是透過不完全恢復,可以保證資料庫的一致性,但是這種辦法要求在歸檔方式下,並且有可用的備份
B. 透過強制性恢復,但是可能導致資料庫不一致。
下面分別用來說明這兩種恢復方法

1.2.1 透過備份來恢復
1、開啟資料庫,會遇到一個類似的錯誤
ORA-00313: open failed for members of log group 1 of thread 1
ORA-00312: online log 1 thread 1: 'D:ORACLEORADATATESTREDO01.LOG'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) 系統找不到指定的檔案

2、檢視V$log,發現是當前日誌
SQL> select group#,sequence#,archived,status from v$log;

GROUP# SEQUENCE# ARCHIVED STATUS
---------- ---------- -------- ----------------
1 1 NO CURRENT
2 2 YES INACTIVE
3 3 YES INACTIVE

3、發現clear不成功
SQL> alter database clear unarchived logfile group 1;
alter database clear unarchived logfile group 1
*
ERROR at line 1:
ORA-01624: log 1 needed for crash recovery of thread 1
ORA-00312: online log 1 thread 1: 'D:ORACLEORADATATESTREDO01.LOG'

4、複製有效的資料庫的全備份,並不完全恢復資料庫
可以採用獲取最近的SCN的辦法用until scn恢復或用until cnacel恢復
recover database until cancel
先選擇auto,儘量恢復可以利用的歸檔日誌,然後重新
recover database until cancel
這次輸入cancel,完成不完全恢復,也就是說恢復兩次。
如:
SQL> recover database until cancel;
Auto
……
SQL> recover database until cancel;
Cancel;
5、利用alter database open resetlogs開啟資料庫
說明:
1、這種辦法恢復的資料庫是一致的不完全恢復,會丟失當前聯機日誌中的事務資料
2、這種方法適合於歸檔資料庫並且有可用的資料庫全備份。
3、恢復成功之後,記得再做一次資料庫的全備份。
4、建議聯機日誌檔案一定要實現鏡相在不同的磁碟上,避免這種情況的發生,因為任何資料的丟失對於生產來說都是不容許的。

1.2.2 如果沒有備份,進行強制性恢復
1、開啟資料庫,會遇到一個類似的錯誤
ORA-00313: open failed for members of log group 1 of thread 1
ORA-00312: online log 1 thread 1: 'D:ORACLEORADATATESTREDO01.LOG'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) 系統找不到指定的檔案

2、檢視V$log,發現是當前日誌
SQL> select group#,sequence#,archived,status from v$log;

GROUP# SEQUENCE# ARCHIVED STATUS
---------- ---------- -------- ----------------
1 1 NO CURRENT
2 2 YES INACTIVE
3 3 YES INACTIVE

3、發現clear不成功
SQL> alter database clear unarchived logfile group 1;
alter database clear unarchived logfile group 1
*
ERROR at line 1:
ORA-01624: log 1 needed for crash recovery of thread 1
ORA-00312: online log 1 thread 1: 'D:ORACLEORADATATESTREDO01.LOG'

4、把資料庫down掉
SQL>shutdown immediate

5、在init.ora中加入如下引數
_allow_resetlogs_corruption=TRUE

6、重新啟動資料庫,利用until cancel恢復
SQL>recover database until cancel;
Cancel
如果出錯,不再理會,發出
SQL>alter database open resetlogs;

7、資料庫被開啟後,馬上執行一個full export

8、shutdown資料庫,去掉_all_resetlogs_corrupt引數

9、重建庫

10、import並完成恢復

11、建議執行一下ANALYZE TABLE ...VALIDATE STRUCTURE CASCADE;
說明:
1、該恢復方法是沒有辦法之後的恢復方法,一般情況下建議不要採用,因為該方法可能導致資料庫的不一致
2、該方法也丟失資料,但是丟失的資料沒有上一種方法的資料多,主要是未寫入資料檔案的已提交或未提交資料。
3、建議成功後嚴格執行以上的7到11步,完成資料庫的檢查與分析
4、全部完成後做一次資料庫的全備份
5、建議聯機日誌檔案一定要實現鏡相在不同的磁碟上,避免這種情況的發生,因為任何資料的丟失對於生產來說都是不容許的。


二、損壞控制檔案的恢復方法

2.1 損壞單個控制檔案
損壞單個控制檔案是比較容易恢復的,因為一般的資料庫系統,控制檔案都不是一個,而且所有的控制檔案都互為鏡相,只要複製一個好的控制檔案替換壞的控制檔案就可以了。
1、控制檔案損壞,最典型的就是啟動資料庫出錯,不能mount資料庫
SQL>startup
ORA-00205: error in identifying controlfile, check alert log for more info
檢視報警日誌檔案,有如下資訊
alter database mount
Mon May 26 11:59:52 2003
ORA-00202: controlfile: 'D:Oracleoradatachencontrol01.ctl'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) 系統找不到指定的檔案。

2、停止資料庫
SQL>shutdown immediate

3、複製一個好的控制檔案替換壞的控制檔案或修改init.ora中的控制檔案引數,取消這個壞的控制檔案。

4、重新啟動資料
SQL>startup
說明:
1、損失單個控制檔案是比較簡單的,因為資料庫中所有的控制檔案都是鏡相的,只需要簡單的複製一個好的就可以了
2、建議鏡相控制檔案在不同的磁碟上
3、建議多做控制檔案的備份,長期保留一份由alter database backup control file to trace產生的控制檔案的文字備份

2.2 損壞全部控制檔案
損壞多個控制檔案,或者人為的刪除了所有的控制檔案,透過控制檔案的複製已經不能解決問題,這個時候需要重新建立控制檔案。
同時注意,alter database backup control file to trace可以產生一個控制檔案的文字備份。
以下是詳細重新建立控制檔案的步驟
1、關閉資料庫
SQL>shutdown immediate;
2、刪除所有控制檔案,模擬控制檔案的丟失

3、啟動資料庫,出現錯誤,並不能啟動到mount下
SQL>startup
ORA-00205: error in identifying controlfile, check alert log for more info
檢視報警日誌檔案,有如下資訊
alter database mount
Mon May 26 11:53:15 2003
ORA-00202: controlfile: 'D:Oracleoradatachencontrol01.ctl'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) 系統找不到指定的檔案。

4、關閉資料庫
SQL>shutdown immediate;

5、在internal或sys下執行如下建立控制檔案的指令碼,注意完整列出聯機日誌或資料檔案的路徑,或修改由alter database backup control file to trace備份控制檔案時產生的指令碼,去掉多餘的註釋即可。
STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE "TEST" NORESETLOGS NOARCHIVELOG
MAXLOGFILES 32
MAXLOGMEMBERS 2
MAXDATAFILES 254
MAXINSTANCES 1
MAXLOGHISTORY 226
LOGFILE
GROUP 1 'D:ORACLEORADATATESTREDO01.LOG' SIZE 1M,
GROUP 2 'D:ORACLEORADATATESTREDO02.LOG' SIZE 1M,
GROUP 3 'D:ORACLEORADATATESTREDO03.LOG' SIZE 1M
DATAFILE
'D:ORACLEORADATATESTSYSTEM01.DBF',
'D:ORACLEORADATATESTRBS01.DBF',
'D:ORACLEORADATATESTUSERS01.DBF',
'D:ORACLEORADATATESTTEMP01.DBF',
'D:ORACLEORADATATESTTOOLS01.DBF',
'D:ORACLEORADATATESTINDX01.DBF'
CHARACTER SET ZHS16GBK;

-- Recovery is required if any of the datafiles are restored backups,
-- or if the last shutdown was not normal or immediate.
RECOVER DATABASE
--if the last shutdown was not normal or immediate
--noarchive
-- RECOVER DATABASE UNTIL CANCELUSING BACKUP CONTROLFILE
--archive
-- RECOVER DATABASE USING BACKUP CONTROLFILE UNTIL CANCEL
-- Database can now be opened normally.
ALTER DATABASE OPEN;
--if recover database until cancel
--ALTER DATABASE OPEN RESETLOGS;
6、如果沒有錯誤,資料庫將啟動到open狀態下。

說明:
1、重建控制檔案用於恢復全部資料檔案的損壞,需要注意其書寫的正確性,保證包含了所有的資料檔案與聯機日誌
2、經常有這樣一種情況,因為一個磁碟損壞,我們不能再恢復(store)資料檔案到這個磁碟,因此在store到另外一個盤的時候,我們就必須重新建立控制檔案,用於識別這個新的資料檔案,這裡也可以用這種方法用於恢復

三、損壞回滾資料檔案的恢復方法
回滾段表空間中的一個資料檔案丟失或者損壞導致資料庫無法識別它,在啟動資料庫的時候會出現ORA-1157, ORA-1110的錯誤,或者作業系統級別的錯誤,例如ORA-7360。在關閉資料庫的時候(normal或者immediate)會出現ORA-1116, ORA-1110的錯誤,或者作業系統級別的錯誤,例如ORA-7368。

3.1 損壞資料檔案,但資料庫處於Open狀態
如果你發現有回滾段的資料檔案丟失或者損壞了,而此時的資料庫是處於開啟的狀態下並且在執行,就千萬不要關閉資料庫了,因為在大多數的情況下開啟的時候比關閉的時候好解決問題一些。
一般也是存在有兩種情況:
A、是offline丟失或損壞的資料檔案,然後從一個備份中恢復,執行介質恢復以保持一致性。但是這種情況要求資料庫是歸檔方式下才可以採用的。
B、是offline那個存在丟失或損壞的資料檔案所在的整個回滾段表空間,然後刪除整個回滾段表空間並重建,但是你必須要殺掉那些在回滾段中已經啟用的使用者程式才可以offline的。
通常第一種情況就比較簡單實現,但是更多的使用者事務將會出錯並且回滾。
A的具體步驟:
1、offline丟失或損壞的資料檔案
ALTER DATABASE DATAFILE '' OFFLINE;
2、從一個有效的備份中恢復。
3、執行以下查詢
SELECT V1.GROUP#, MEMBER, SEQUENCE#
FROM V$LOG V1, V$LOGFILE V2
WHERE V1.GROUP# = V2.GROUP# ;
這個將列出你的所有redolog檔案以及它們所代表的sequence numbers。
4、恢復資料檔案。
RECOVER DATAFILE ''
5、確信你應用了所有的redolog檔案,直至出現提示資訊"Media recovery complete"。
6、online那個資料檔案。
ALTER DATABASE DATAFILE '' ONLINE;

B的具體步驟:
1、offline存在丟失或損壞的資料檔案的回滾段表空間中的所有回滾段。
ALTER ROLLBACK SEGMENT OFFLINE;
2、檢測當然回滾段的狀態。
SELECT SEGMENT_NAME, STATUS FROM DBA_ROLLBACK_SEGS
WHERE TABLESPACE_NAME = '';
3、刪除所有offline的回滾段
DROP ROLLBACK SEGMENT ;
4、處理那些online狀態的回滾段。
重新執行第二步的查詢
如果你已經執行過offline操作的回滾段狀態仍然是online,則說明這個回滾段內有活動的事務。你要接著查詢
SELECT SEGMENT_NAME, XACTS ACTIVE_TX, V.STATUS
FROM V$ROLLSTAT V, DBA_ROLLBACK_SEGS
WHERE TABLESPACE_NAME = '' AND SEGMENT_ID = USN;
如果沒有返回結果,則證明存在丟失或損壞的資料檔案的回滾段表空間中的所有回滾段都已經被offline了,然後重新執行第二步,第三步。如果查詢有結果返回,則狀態應該是"PENDING OFFLINE".接著檢視ACTIVE_TX列,如果值為0,則表明此回滾段中已經沒有未處理的事務了,很快就會被offline的,然後等它offline後重新執行2,3步後跳至第六步。如果值大於0,則繼續到第五步。
5、強制那些包含活動事務的回滾段offline。
活動的事務應該被提交或者回滾,執行下面的查詢看看哪些使用者佔用了回滾段:
SELECT S.SID, S.SERIAL#, S.USERNAME, R.NAME "ROLLBACK"
FROM V$SESSION S, V$TRANSACTION T, V$ROLLNAME R
WHERE R.NAME IN ('', ... , '')
AND S.TADDR = T.ADDR AND T.XIDUSN = R.USN;
最好能直接聯絡到那些user讓他們自己去回滾或者提交事務,如果不能做到的話,那就只能強制性的殺掉程式了。
ALTER SYSTEM KILL SESSION ', ';
殺掉程式後再過一段時間後回滾段會自動清除那些事務,然後就可以回到第二步繼續查詢了。
6、刪除回滾段。
DROP TABLESPACE INCLUDING CONTENTS;
7、重建回滾段並online它們
說明:
1、資料庫如果是open狀態,就可以直接在open狀態下解決問題,沒有必要停下資料庫,增加down機時間
2、不管上上面那種恢復方法都是正常性的恢復,不會引起資料的不一致或錯誤。

3.2資料庫關閉,但是資料檔案中沒有活動事務
這種情況下最簡單的方法就是offline drop掉這個壞了的或者丟失的資料檔案,然後以restricted模式開啟資料庫然後刪除並且重建包含損壞檔案的回滾段表空間。
具體步驟如下:
1、確定資料庫是正常的關閉的。方法是可以去檢視alert檔案,到最後看是否有如下資訊:
"alter database dismount
Completed: alter database dismount"
如果有的話,就證明資料庫是正常關閉的,否則就不能用這個方法去恢復。
2、修改init引數檔案,移去ROLLBACK_SEGMENTS中包含的損壞資料檔案的回滾段表空間的回滾段,如果你不能確定哪些回滾段是壞的,簡單的方法是你可以註釋掉整個ROLLBACK_SEGMENTS。
3、以restricted模式去mount資料庫。
STARTUP RESTRICT MOUNT
4、offline drop掉那個壞的資料檔案
ALTER DATABASE DATAFILE '' OFFLINE DROP;
5、開啟資料庫
ALTER DATABASE OPEN
如果你看到如下資訊"Statement processed",則跳到第7步,如果你看到ORA-604, ORA-376, and ORA-1110的錯誤資訊,繼續第6步。
6、正常的關閉資料庫,然後在init檔案中註釋掉ROLLBACK_SEGMENTS,並加入隱含引數
_corrupted_rollback_segments = ( ,...., )
然後以restricted模式開啟資料庫
STARTUP RESTRICT
7、刪除掉那個包含損壞檔案的回滾段表空間。
DROP TABLESPACE INCLUDING CONTENTS;
8、重建回滾段表空間,記得建立後要把回滾段都online。
9、重新使資料庫對所有使用者可用。
ALTER SYSTEM DISABLE RESTRICTED SESSION;
10、然後正常關閉資料庫,修改init檔案,如果開始只是註釋掉了ROLLBACK_SEGMENTS的,就去掉註釋即可,如果加了隱含引數的,註釋掉它,並在ROLLBACK_SEGMENTS加入所有的回滾段。
11、正常啟動資料庫。
Startup
說明:
1、這種方法的前提條件是資料庫是正常關閉(不是abort)可用
2、這種方法是正常方法,不會引起資料錯誤

3.3 資料庫關閉,資料檔案中有活動事務,沒有可用備份
一般造成這種原因的情況是採用了shutdown abort或其它原因異常關機(如斷電)導致的。
1、開啟一個事務
SQL> set transaction use rollback segment rbs0;
Transaction set.
SQL> insert into test (a) values (1);
1 row created.

2、異常關閉
SQL> shutdown abort;
ORACLE instance shut down.

3、刪除rbs的一個資料檔案
C:>del D:Oracleoradatachenrbs01.

4、修改INIT.ora
rollback_segments=(system)
新增_corrupted_rollback_segments=(rbs0,rbs1,rbs2……)

5、SQL>Startup mount

6、SQL>alter database datafile ’d:oracleoradatat8irbs01.dbf’ offline drop;
資料庫已更改。

7、SQL>recover database ;
完成介質恢復。

8、SQL>alter database open ;
資料庫已更改。

9、SQL>select * from v$rollname;
USN NAME
----------------- ---------------------
0 SYSTEM

10、SQL>select segment_name,tablespace_name,status from dba_rollback_segs;
SEGMENT_NAME TABLESPACE_NAME STATUS
------------------------------ ------ ------------------------------------
SYSTEM SYSTEM ONLINE
RBS0 RBS NEEDS RECOVERY
RBS1 RBS NEEDS RECOVERY
RBS2 RBS NEEDS RECOVERY

11、SQL>drop rollback segment rbs0;
重算段已丟棄。
SQL>drop rollback segment rbs1;
重算段已丟棄。
SQL>drop rollback segment rbs2;
重算段已丟棄。

12、SQL>select segment_name,tablespace_name,status from dba_rollback_segs;
SEGMENT_NAME TABLESPACE_NAME STATUS
------------------------------ ------ ------------------------------------
SYSTEM SYSTEM ONLINE

13、SQL>drop tablespace rbs including contents;
表空間已丟棄。

14、重建新的回滾表空間及回滾段,並聯機。

15、SQL>shutdown abort

16、再修改INIT.ora
rollback_segments=(rbs0,rbs1,rbs2)
將_corrupted_rollback_segments=(rbs0,rbs1,rbs2)去掉。

17、SQL>startup

1、這種辦法是萬不得以的時候使用的方法,如果有備份,都建議從備份上進行恢復
2、這種方法恢復的資料庫,可能會引起資料庫的資料錯誤
3、恢復成功以後,建議exp/imp資料,並重新分析檢查資料庫

3.4 資料庫關閉,資料檔案中有活動事務,從備份恢復
1、從一個有效的備份中恢復損壞的資料檔案。
2、mount資料庫。
3、執行以下查詢
SELECT FILE#, NAME, STATUS FROM V$DATAFILE;
如果發現要恢復的檔案是offline狀態的話,要先online它
ALTER DATABASE DATAFILE '' ONLINE;
4、執行以下查詢
SELECT V1.GROUP#, MEMBER, SEQUENCE#, FIRST_CHANGE#
FROM V$LOG V1, V$LOGFILE V2
WHERE V1.GROUP# = V2.GROUP# ;
這個將列出redlog檔案所代表的sequence和first change numbers。
5、如果資料庫是非歸檔情況下,執行以下查詢:
SELECT FILE#, CHANGE# FROM V$RECOVER_FILE;
如果CHANGE#大於最小的redolog檔案的FIRST_CHANGE#,則資料檔案可以被恢復,記得在應用日誌的時候要把所有redolog檔案全部應用一遍。
如果CHANGE#小於最小的redolog檔案的FIRST_CHANGE#,則資料檔案就不可以被恢復了,這時候你要從一個有效的全備份中去恢復資料庫了,如果沒有全備份的話,那你就只能把資料庫強制開啟到一個不一致的狀態去exp出資料,然後重新建庫匯入資料,因為這種方式的恢復oracle是不推薦使用者自己做的,所以這裡我就不詳細說明了。
6、恢復資料檔案
RECOVER DATAFILE ''
7、確信你應用了所有的redolog檔案,直至出現提示資訊"Media recovery complete"。
8、開啟資料庫。
說明:
1、這種方法要求在歸檔有備份的方式下進行,而且是建議方式
2、這種方法不會導致資料庫的錯誤

四、損壞臨時資料檔案的恢復方法
臨時資料檔案的恢復是比較簡單的,因為臨時檔案中不涉及到其它的有用的資料,所以可以刪除後重建
1、關閉資料庫
SQL>shutdown immediate
2、刪除臨時資料檔案,模擬媒體失敗

3、啟動資料庫,檢測到檔案錯誤

4、離線該資料檔案
SQL>alter database datafile ‘檔名全名’ offline drop;

5、開啟資料庫
SQL>alter database open

6、刪除該臨時表空間
SQL>drop tablespace temp(或其它臨時表空間名稱);

7、重新建立該表空間,並重新分配給使用者
說明:
1、臨時資料檔案是非重要檔案,不儲存永久資料,可以隨時刪除重建,不影響資料庫的資料安全
2、如果重新建立以後,別忘了重新分配給使用者。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7319461/viewspace-1027113/,如需轉載,請註明出處,否則將追究法律責任。

相關文章