REDO檔案丟失或者損壞的恢復

djb1008發表於2010-09-14
  1. REDO檔案的功能描述

REDO檔案儲存所有資料庫的變更內容和每一次變更所需的重做指令碼,是資料庫不可缺少的一部分,如果REDO GROUP中只有一個REDO檔案,同時這個REDO檔案被損壞,則系統切換到這個REDO GROUP時,資料庫將直接DOWN;如果REDO GROUP中有多個REDO檔案,其中一個或者多個REDO被損壞,只要該組中還有一個好的REDO檔案,則系統將報警(寫入alert.log文件中),資料庫仍然可以正常執行。

REDO檔案在資料庫恢復時提供前滾所需的內容。


檢視REDO 相關資訊的檢視有:V$LOG,V$LOGFILE,V$INSTANCE_RECOVERY

SQL> DESC V$INSTANCE_RECOVERY;

名稱 是否為空? 型別

----------------------------------------- -------- ------

RECOVERY_ESTIMATED_IOS NUMBER

ACTUAL_REDO_BLKS NUMBER

TARGET_REDO_BLKS NUMBER

LOG_FILE_SIZE_REDO_BLKS NUMBER

LOG_CHKPT_TIMEOUT_REDO_BLKS NUMBER

LOG_CHKPT_INTERVAL_REDO_BLKS NUMBER

FAST_START_IO_TARGET_REDO_BLKS NUMBER

TARGET_MTTR NUMBER

ESTIMATED_MTTR NUMBER

CKPT_BLOCK_WRITES NUMBER

OPTIMAL_LOGFILE_SIZE NUMBER

ESTD_CLUSTER_AVAILABLE_TIME NUMBER

WRITES_MTTR NUMBER

WRITES_LOGFILE_SIZE NUMBER

WRITES_LOG_CHECKPOINT_SETTINGS NUMBER

WRITES_OTHER_SETTINGS NUMBER

WRITES_AUTOTUNE NUMBER

WRITES_FULL_THREAD_CKPT NUMBER

一般情況下,最好有3-5REDO GROUP,每個REDO GROUP中有兩個成員,放在不同的磁碟資源上。同一個REDO GROUP 中的REDO檔案的大小盡量設定為相同,否則系統以最小的一個為基準,比較浪費空間。各個REDO GROUP 的大小也最好一致。

  1. REDO檔案恢復例項

2.1檢視REDO 相關檢視

SQL> select * from v$log;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME

---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- -------------------

1 1 14 10485760 2 YES ACTIVE 1304089 2006-07-06 12:33:59

2 1 15 10485760 2 YES INACTIVE 1314889 2006-07-06 15:55:10

3 1 16 10485760 2 NO CURRENT 1323514 2006-07-07 08:33:21

STATUS狀態的解釋:

CURRENT: 當前的REDO檔案,REDO BUFFER 的內容由LGWR程式寫入當前REDO檔案,如果丟失該組檔案,會造成資料的丟失.

ACTIVE : 檔案中含有的內容還沒有寫入到ARCHIVELOG檔案中,如果丟失該組檔案也會造成資料的丟失.

INACTIVE: 已經歸檔,丟失檔案不會造成資料丟失,不過在做資料庫的恢復時,該組檔案可以用來做前滾操作.

SQL> SELECT * FROM V$LOGFILE ORDER BY GROUP#;

GROUP# STATUS TYPE MEMBER IS_

---------- ------- ------- ------------------------------ ---

1 ONLINE C:ORADATAAIDUREDO01.LOG NO

1 ONLINE C:ORADATAAIDUREDO01B.LOG NO

2 ONLINE C:ORADATAAIDUREDO02.ORA NO

2 ONLINE C:ORADATAAIDUREDO02B.ORA NO

3 ONLINE C:ORADATAAIDUREDO03.LOG NO

3 ONLINE C:ORADATAAIDUREDO03B.LOG NO

已選擇6行。

可以看到,當前資料庫有3REDO GROUP,每個GROUP 含有兩個MEMBER(REDO檔案).

2.2 增加REDO GROUP

SQL> alter database add logfile group 4 'C:ORADATAAIDUREDO04.ORA' SIZE 10M REUSE;

資料庫已更改。

SQL> SELECT * FROM V$LOGFILE ORDER BY GROUP#;

GROUP# STATUS TYPE MEMBER IS_

---------- ------- ------- ------------------------------ ---

1 ONLINE C:ORADATAAIDUREDO01B.LOG NO

1 ONLINE C:ORADATAAIDUREDO01.LOG NO

2 ONLINE C:ORADATAAIDUREDO02.ORA NO

2 ONLINE C:ORADATAAIDUREDO02B.ORA NO

3 ONLINE C:ORADATAAIDUREDO03B.LOG NO

3 ONLINE C:ORADATAAIDUREDO03.LOG NO

4 ONLINE C:ORADATAAIDUREDO04.ORA NO

已選擇7行。

2.3 刪除REDO GROUP

SQL> ALTER DATABASE DROP LOGFILE GROUP 4;

資料庫已更改。

SQL> SELECT * FROM V$LOGFILE ORDER BY GROUP#;

GROUP# STATUS TYPE MEMBER IS_

---------- ------- ------- ------------------------------ ---

1 ONLINE C:ORADATAAIDUREDO01.LOG NO

1 ONLINE C:ORADATAAIDUREDO01B.LOG NO

2 ONLINE C:ORADATAAIDUREDO02.ORA NO

2 ONLINE C:ORADATAAIDUREDO02B.ORA NO

3 ONLINE C:ORADATAAIDUREDO03.LOG NO

3 ONLINE C:ORADATAAIDUREDO03B.LOG NO

已選擇6行。

2.4 REDO GROUP中增加REDO檔案(MEMBER

SQL> ALTER DATABASE ADD LOGFILE MEMBER 'C:ORADATAAIDUREDO01C.LOG' TO GROUP 1;

資料庫已更改。

SQL> SELECT * FROM V$LOGFILE ORDER BY GROUP#;

GROUP# STATUS TYPE MEMBER IS_

---------- ------- ------- ------------------------------ ---

1 INVALID ONLINE C:ORADATAAIDUREDO01C.LOG NO

1 ONLINE C:ORADATAAIDUREDO01.LOG NO

1 ONLINE C:ORADATAAIDUREDO01B.LOG NO

2 ONLINE C:ORADATAAIDUREDO02.ORA NO

2 ONLINE C:ORADATAAIDUREDO02B.ORA NO

3 ONLINE C:ORADATAAIDUREDO03.LOG NO

3 ONLINE C:ORADATAAIDUREDO03B.LOG NO

已選擇7行。

我們注意到新建的MEMBER的狀態為INVALID,這個不用擔心,等下次切換到該組,然後狀態就會修改為正常。

2.5 REDO GROUP中刪除REDO 檔案(MEMBER

SQL> ALTER DATABASE DROP LOGFILE MEMBER 'C:ORADATAAIDUREDO01C.LOG';

資料庫已更改。

SQL> SELECT * FROM V$LOGFILE ORDER BY GROUP#;

GROUP# STATUS TYPE MEMBER IS_

---------- ------- ------- ------------------------------ ---

1 ONLINE C:ORADATAAIDUREDO01.LOG NO

1 ONLINE C:ORADATAAIDUREDO01B.LOG NO

2 ONLINE C:ORADATAAIDUREDO02.ORA NO

2 ONLINE C:ORADATAAIDUREDO02B.ORA NO

3 ONLINE C:ORADATAAIDUREDO03.LOG NO

3 ONLINE C:ORADATAAIDUREDO03B.LOG NO

已選擇6行。

注意: 不可以刪除REDO GROUP 中所有的REDO 檔案,這樣會報錯,如下所示:

SQL> ALTER DATABASE DROP LOGFILE MEMBER 'C:ORADATAAIDUREDO01.LOG';

資料庫已更改。

SQL> ALTER DATABASE DROP LOGFILE MEMBER 'C:ORADATAAIDUREDO01B.LOG';

ALTER DATABASE DROP LOGFILE MEMBER 'C:ORADATAAIDUREDO01B.LOG'

* 1 行出現錯誤:

ORA-00361: 無法刪除最後一個日誌成員 C:ORADATAAIDUREDO01B.LOG ( 1)

2.6 已經歸檔的REDO檔案損壞的恢復

所謂已經歸檔的REDO檔案就是在V$LOG檢視中狀態為INACTIVEREDO檔案。

這些文件的丟失,不會對資料庫造成任何影響,但需要及時的恢復,否則切換到這個組時將會發生錯誤。

解決問題有兩個辦法:

  1. 刪除這個REDO GROUP,記住刪除後資料庫的REDO GROUP數目不應小於2,如果當前REDO GROUP數目為2,則不可以使用這個辦法。
  2. 在組中增加新的同樣大小的REDO檔案,然後刪除原來的MEMBER。增加、刪除REDO檔案的方法見上面的2.4,2.5

2.7沒有歸檔的REDO檔案損壞的恢復

2.7.1 簡述

所謂沒有歸檔的REDO檔案就是在V$LOG檢視中狀態為ACTIVE,CURRENTREDO檔案。如果沒有歸檔的REDO GROUP中含有多個REDO 檔案,丟失或者損壞的只是部分REDO檔案,則可以透過複製正常的REDO檔案,覆蓋損壞的REDO檔案的方式解決問題,資料不會丟失,不用做恢復操作。

如果沒有歸檔的REDO GROUP組中所有的REDO檔案都丟失或者損壞,將會導致資料庫資料丟失,如果沒有歸檔的REDO GROUP 為當前組,則資料庫立即DOWN機。當這個情況發生時,就意味著資料的丟失,我們只能將資料庫恢復到前一次的歸檔日誌切換時刻。

2.7.2 建立測試環境

檢查當前的REDO GROUP為第1.

SQL> SELECT * FROM V$LOG;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS

---------- ---------- ---------- ---------- ---------- --- ----------------

FIRST_CHANGE# FIRST_TIME

------------- -------------------

1 1 17 10485760 1 NO CURRENT

1333209 2006-07-07 11:47:23

2 1 15 10485760 2 YES INACTIVE

1314889 2006-07-06 15:55:10

3 1 16 10485760 2 YES INACTIVE

1323514 2006-07-07 08:33:21

建立一個測試表,這個資料庫的變化存放在當前的REDO檔案中。

SQL> CREATE TABLE AIDU.TEST_FOR_REDO AS SELECT * FROM AIDU.TEST02;

表已建立。

2.7.3 模擬災難發生

SQL> SHUTDOWN ABORT;

ORACLE 例程已經關閉

SQL>HOST DELETE C:ORADATAAIDUREDO01*.* #刪除當前日誌組的所有成員檔案

SQL> STARTUP #啟動資料庫時將報找不到資料庫檔案的錯誤,資料庫只能啟動到MOUNT狀態。

ORA-32004: obsolete and/or deprecated parameter(s) specified

ORACLE 例程已經啟動。

Total System Global Area 268435456 bytes

Fixed Size 1248504 bytes

Variable Size 96469768 bytes

Database Buffers 167772160 bytes

Redo Buffers 2945024 bytes

資料庫裝載完畢。

ORA-00313: 無法開啟日誌組 1 (用於執行緒 1) 的成員

ORA-00312: 聯機日誌 1 執行緒 1: 'C:ORADATAAIDUREDO01B.LOG'

ORA-27041: 無法開啟檔案

OSD-04002: 無法開啟檔案

O/S-Error: (OS 2) 系統找不到指定的檔案。

SQL> SELECT OPEN_MODE FROM V$DATABASE;

OPEN_MODE

----------

MOUNTED

2.7.4 進行災難恢復

嘗試使用RESETLOG或者NORESETLOGS開啟資料庫,結果失敗

SQL> alter database open resetlogs;

alter database open resetlogs

* 1 行出現錯誤:

ORA-01139: RESETLOGS 選項僅在不完全資料庫恢復後有效

SQL> alter database open noresetlogs;

alter database open noresetlogs

* 1 行出現錯誤:

ORA-01139: RESETLOGS 選項僅在不完全資料庫恢復後有效

嘗試刪除當前被破壞的REDO GROUP,結果失敗

SQL> alter database drop logfile group 1;

alter database drop logfile group 1

*

1 行出現錯誤:

ORA-01623: 日誌 1 是例項 aidu (執行緒 1) 的當前日誌 - 無法刪除

ORA-00312: 聯機日誌 1 執行緒 1: 'C:ORADATAAIDUREDO01B.LOG'

清除當前日誌組的內容,然後重新建立

SQL> ALTER DATABASE CLEAR UNARCHIVED LOGFILE GROUP 1;

* 1 行出現錯誤:

ORA-01624: 日誌 1 是緊急恢復例項 aidu (執行緒 1) 所必需的

ORA-00312: 聯機日誌 1 執行緒 1: 'C:ORADATAAIDUREDO01B.LOG'

這樣我們只能做不完全的恢復了,恢復的方法有兩個:

  1. 使用RMAN或者手工進行基於CANCEL的恢復。

SQL>SHUTDOWN IMMEDIATE;

手工刪除資料檔案(DATAFILE

C:>RMAN TARGET /

RMAN>STARTUP MOUNT

RMAN>RUN{

ALLOCATE CHANNEL D1 TYPE DISK;

RESTORE DATABASE;

RECOVER DATABASE;

RELEASE CHANNEL D1;}

RMAN>ALTER DATABASE OPEN RESETLOGS;

這裡不詳細討論RMAN的恢復。

  1. 使用EXP,IMP進行恢復。

具體操作步驟如下:

SQL>SHUTDOWN IMMEDIATE;

init.ora中加入引數: _allow_resetlogs_corruption=TRUE

重新啟動資料庫,利用until cancel恢復

SQL>recover database until cancel;

Cancel

如果出錯,不再理會,發出

SQL>alter database open resetlogs;

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

shutdown資料庫,去掉_all_resetlogs_corrupt引數

重建庫

import並完成恢復

建議執行一下ANALYZE TABLE ...VALIDATE STRUCTURE CASCADE

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

相關文章