淺談關於redo log file的故障處理

  如果LGWR 至少能夠訪問一個組內成員,對組內可訪問成員的寫入將照常進行,LGWR 忽略組內的不可用成員。如果該組不活動,即檢查點已完成,那麼丟棄和添加一個新的聯機日誌成員就可以解決問題,否則如果該組是當前活動的日誌組,則必須首先強制日誌切換。
 
SQL> SELECT group#, sequence#, bytes, members, status
 2 FROM V$LOG;
    GROUP# SEQUENCE#      BYTES    MEMBERS STATUS
---------- ---------- ---------- ---------- ----------------
         1        411    1048576          2 INACTIVE
         2        412    1048576          2 INACTIVE
         3        413    1048576          2 INACTIVE
         5        414    1048576          2 CURRENT
SQL> select * from v$logfile
 2 ORDER BY GROUP#;
 
    GROUP# STATUS MEMBER
---------- ------- ----------------------------------------------------------
         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG
         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG
         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG
         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG
         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG
         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG
         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG
         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG
8 rows selected
SQL>
 
爲了模擬日誌組中有一個成員損壞的情況,我們打開文本編輯器,並且破壞E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG文件,然後,我們看到:
 
SQL> select * from v$logfile;
    GROUP# STATUS MEMBER
---------- ------- -------------------------------------------------------
         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG
         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG
         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG
         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG
         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG
         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG
         5 INVALID E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG
         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG
8 rows selected
SQL>
 
但是這時候數據還可以忽略這個損壞的文件而正常使用。要修復這個文件,我們需要做:
SQL> shutdown
數據庫已經關閉。
已經卸載數據庫。
ORACLE 例程已經關閉。
SQL> host
Microsoft Windows 2000 [Version 5.00.2195]
(C) 版權所有 1985-2000 Microsoft Corp.
E:/>COPY E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG E:/ORACLE1/ORA81/ORADATA/TEST/
REDO07.LOG
改寫 E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG 嗎? (Yes/No/All): YES
已複製         1 個文件。
 
上面這一步需要注意的是,如果新的日誌文件的位置或文件名稱需要改變(如,介質失效),則在數據庫加載(Startup Mount)後需要對這個改變位置或名稱的日誌文件重命名,然後再打開數據,具體過程參見重新定位或者重命名聯機重做日誌文件
 
E:/>exit
SQL> startup
ORACLE 例程已經啓動。
Total System Global Area   36214812 bytes
Fixed Size                    75804 bytes
Variable Size              19283968 bytes
Database Buffers           16777216 bytes
Redo Buffers                  77824 bytes
數據庫裝載完畢。
數據庫已經打開。
SQL> select * from v$logfile;
    GROUP# STATUS MEMBER
---------- ------- ------------------------------------------------------------
         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG
         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG
         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG
         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG
         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG
         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG
         5 UNKNOWN E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG
         5 STALE   E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG
8 rows selected
SQL> alter system switch logfile;
System altered
SQL> select * from v$logfile;
    GROUP# STATUS MEMBER
---------- ------- -------------------------------------------------------
         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG
         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG
         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG
         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG
         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG
         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG
         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG
         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG
8 rows selected
SQL>
然後,看到一切正常了,則完全關閉數據(Normal),進行一個冷備份。
上面關於日誌文件損壞和修復的相關部分會被記錄在Alert.log文件中。
 
2        如果在日誌切換時LGWR 無法訪問下一個組的所有成員或者損壞的日誌文件時改組中日誌成員,則該實例關閉。如果組不活動,那麼丟棄和添加一個新的日誌組就可解決問題;如果活動,數據庫可能需要從聯機重做日誌文件殘留物進行介質恢復。
 
SQL> ALTER DATABASE DROP LOGFILE MEMBER 'E:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG';
Database altered
SQL> select * from v$logfile;
    GROUP# STATUS MEMBER
---------- ------- -----------------------------------------------------------
         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG
         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG
         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG
         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG
         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG
         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG
         5         E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG
7 rows selected
SQL>
 
爲了模擬日誌組中有一個成員損壞的情況,我們打開文本編輯器,並且破壞E:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG文件,然後,我們看到:
SQL> ALTER SYSTEM SWITCH LOGFILE;
ALTER SYSTEM SWITCH LOGFILE
ORA-00313: 無法打開日誌組 (線程 ) 的成員
SQL> STARTUP MOUNT
ORACLE 例程已經啓動。
Total System Global Area   36214812 bytes
Fixed Size                    75804 bytes
Variable Size              19283968 bytes
Database Buffers           16777216 bytes
Redo Buffers                  77824 bytes
數據庫裝載完畢。
SQL> ALTER DATABASE
 2 DROP LOGFILE GROUP 5;
數據庫已更改。
SQL> ALTER DATABASE OPEN;
數據庫已更改。
SQL> select * from v$logfile;
    GROUP# STATUS MEMBER
---------- ------- -------------------------------------------------
         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG
         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG
         3 STALE   D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG
         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG
         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG
         3 STALE   E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG
6 rows selected
SQL>
然後,看到一切正常了,則完全關閉數據(Normal),進行一個冷備份。
上面關於日誌文件損壞和修復的相關部分會被記錄在Alert.log文件中。
 
在歸檔模式下,我們需要用alter database clear logfile group來恢復數據庫:
SQL> select * from  v$logfile;
    GROUP# STATUS MEMBER
---------- ------- --------------------------------------------------------
         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG
         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG
         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG
         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG
         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG
         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG
         4         F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG
         4         F:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG
8 rows selected
 
 
我們用GROUP4作試驗,首先確定它不是CURRENT GROUP:
SQL> SELECT group#, sequence#, bytes, members, status from v$log;
 
    GROUP# SEQUENCE#      BYTES    MEMBERS STATUS
---------- ---------- ---------- ---------- ----------------
         1        440    1048576          2 INACTIVE
         2        442    1048576          2 CURRENT
         3        439    1048576          2 INACTIVE
         4        441    1048576          2 INACTIVE
 
 
然後讓GRUP4只有一個MEMBER(DROP掉GROUP4中其餘的MEMBER):
SQL> alter database drop logfile member 'F:/ORACLE1/ORA81/ORADATA/TEST/REDO08.LOG';
Database altered
SQL> select * from v$logfile;
    GROUP# STATUS MEMBER
---------- ------- ------------------------------------------------------------
         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG
         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG
         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG
         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG
         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG
         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG
         4         F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG
7 rows selected
SQL>
 
現在GROUP 4中只有一個MEMBER,並且不是CURRENT,我們損壞這個GROUP(F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG),然後,當SWITCH到這個損壞的組以後,數據庫會HANG或者嚴重的話會CRASH,這時候我們可能收到下面的錯誤:
SQL> ALTER DATABASE CLEAR LOGFILE
 2 'F:/oracle1/ora81/oradata/test/REDO07.LOG';
ALTER DATABASE CLEAR LOGFILE
*
ERROR 位於第 1 行:
ORA-12571: TNS:packet writer failure
 
SQL> conn intenral@test
請輸入口令:
ERROR:
ORA-01092: ORACLE instance terminated. Disconnection forced
SQL>
 
這時候,我們可以退出SQLPLUS,然後重新進來:
SQL> exit
E:/>sqlplus internal
SQL*Plus: Release 8.1.7.0.0 - Production on 星期一 10月 7 23:46:17 2002
(c) Copyright 2000 Oracle Corporation. All rights reserved.
連接到:
Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
With the Partitioning option
JServer Release 8.1.7.0.0 - Production
 
進來後,shutdown abort數據庫,然後,再startup mount:
SQL> shutdown abort
ORACLE 例程已經關閉。
SQL> startup mount
ORACLE 例程已經啓動。
Total System Global Area   36214812 bytes
Fixed Size                    75804 bytes
Variable Size              19283968 bytes
Database Buffers           16777216 bytes
Redo Buffers                  77824 bytes
數據庫裝載完畢。
 
可以看到,數據庫沒有CRASH。現在我們CLEAR GROUP4,先用alter database clear logfile group 4;(如果不行就用alter database clear unarchived logfile group 4;):
SQL> alter database clear logfile group 4;
數據庫已更改。
SQL> alter database open;
數據庫已更改。
SQL>
 
好了,數據庫已經恢復了:
SQL> select * from v$logfile;
    GROUP# STATUS MEMBER
---------- ------- ---------------------------------------------------------
         1 STALE   D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG
         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG
         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG
         1 STALE   E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG
         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG
         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG
         4         F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG
7 rows selected
SQL> SELECT group#, sequence#, bytes, members, status from v$log;
    GROUP# SEQUENCE#      BYTES    MEMBERS STATUS
---------- ---------- ---------- ---------- ----------------
         1        448    1048576          2 INACTIVE
         2        446    1048576          2 INACTIVE
         3        447    1048576          2 INACTIVE
         4        449    1048576          1 CURRENT
SQL> alter system switch logfile;
System altered
SQL> SELECT group#, sequence#, bytes, members, status from v$log;
    GROUP# SEQUENCE#      BYTES    MEMBERS STATUS
---------- ---------- ---------- ---------- ----------------
         1        448    1048576          2 INACTIVE
         2        450    1048576          2 CURRENT
         3        447    1048576          2 INACTIVE
         4        449    1048576          1 ACTIVE
SQL>
 
相關討論:
如果一個TRANSACTION開始運行,這是開始寫GROUP 1,沒有COMMIT和ROLLBACK,一直到CURRENT=5,然而,這是正在歸檔2,可是4壞了,那麼這樣恢復後,數據會丟失麼麼?
答:不會。    因爲,首先GROUP 4 不是CURRENT,那麼當SWITCH 從GROUP 4 SWITCH到 GROUP 5的時候,已經發生了CHECKPOINT,也就是說,DBWR已經把數據存儲在了DATAFILE,所以,在實例恢復的時候,系統檢查到GROUP5(CURRENT),發現需要做回滾,於是到回滾段中讀取所要的數據進行回滾。
    那麼如果在從GROUP 4 SWITCH到GROUP 5時要發生CHECKPOINT,並且因爲如果系統慢或要寫的數據塊多,或什麼其它原因,CHECKPOINT還沒結束4也壞了,INSTANCE也CRASH了,這時重起時INSTANCE RECOVER是需要GROUP 4的,這是會丟失數據麼?
答:顯然會。因爲在實例恢復的時候,因爲沒有CHECKPOINT,所以數據還沒有記錄到DATAFILE,所以數據庫不知道如何的做前滾,所以,數據庫就不能OPEN。
 
 
 
2        如果正在寫入當前組的所有成員時,LGWR 突然無法訪問這些成員,則該數據庫例程關閉,在這種情況下,數據庫可能需要從聯機日誌文件殘留物進行介質恢復。
確定GROUP4是CURRENT,如果不是,則做alter system switch logfile;直到GROUP4是CURRENT:
SQL> SELECT group#, sequence#, bytes, members, status from v$log;
    GROUP# SEQUENCE#      BYTES    MEMBERS STATUS
---------- ---------- ---------- ---------- ----------------
         1        452    1048576          2 INACTIVE
         2        450    1048576          2 INACTIVE
         3        451    1048576          2 INACTIVE
         4        453    1048576          1 CURRENT
SQL> select * from v$logfile;
    GROUP# STATUS MEMBER
---------- ------- ---------------------------------------------------------
         1         D:/ORACLE1/ORA81/ORADATA/TEST/REDO01.LOG
         2         D:/ORACLE1/ORA81/ORADATA/TEST/REDO02.LOG
         3         D:/ORACLE1/ORA81/ORADATA/TEST/REDO03.LOG
         1         E:/ORACLE1/ORA81/ORADATA/TEST/REDO04.LOG
         2         E:/ORACLE1/ORA81/ORADATA/TEST/REDO05.LOG
         3         E:/ORACLE1/ORA81/ORADATA/TEST/REDO06.LOG
         4         F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG
7 rows selected
SQL>
 
 
現在毀壞GROUP4。當你發現這個錯誤:
SQL> alter database open;
alter database open
*
ERROR 位於第 1 行:
ORA-00313: ??????? 4 (?? 1) ???
ORA-00312: ???? 4 ?? 1: 'F:/ORACLE1/ORA81/ORADATA/TEST/REDO07.LOG'
SQL>
 
那麼,然後SHUTDOWN,並且MOUNT數據庫:
SQL> shutdown
ORA-01109: ??????
已經卸載數據庫。
ORACLE 例程已經關閉。
SQL> startup mount
ORACLE 例程已經啓動。
Total System Global Area   36214812 bytes
Fixed Size                    75804 bytes
Variable Size              19283968 bytes
Database Buffers           16777216 bytes
Redo Buffers                  77824 bytes
數據庫裝載完畢。
 
恢復數據庫:
SQL> recover database until cancel;
完成介質恢復。
SQL> alter database open resetlogs;
數據庫已更改。
SQL>
SQL> archive log list
數據庫日誌模式            存檔模式
自動存檔             啓用
存檔終點            d:/oracle1/ora81/oradata/test/archive
最早的概要信息日誌序列     1
下一個存檔日誌序列   1
當前日誌序列           1
SQL>
 
以前的ARCHIVE 已經不可用了,需要SHUTDOW,然後作一個FULL BACKUP,之後,再重新STARTUP數據庫,就可以了。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章