一次資料檔案映象丟失引起的故障解決

realkid4發表於2016-10-17

 

DBA而言,世間最悲催的事情不外於由於軟硬體故障(硬體居多)引起的資料丟失,同時發現沒有備份,恢復無門。但是,筆者並不認為“歸檔模式+若干備份”是避免出現問題的法寶。“狡兔三窟”,事先多留退路可能是成熟DBA應有的職業素養。關鍵時刻,一個幾天前的Dump檔案、幾個月前的配置表和系統特性往往是拯救DBA職業生命的關鍵。

 

資料檔案丟失、損壞這樣的錯誤,隨著管理人員水平的提升和技術保障,已經很少在行業中聽到的。相對於軟體故障,基礎環境硬體故障和人為操作故障,常常是我們面對故障的直接因素。在這樣的背景下,規範的操作、對系統資料的熟悉程度和穩妥的處置是我們避免問題進一步惡化,最大限度挽回損失的重要措施。

 

本篇主要介紹筆者遇到的檔案丟失故障。

 

1、問題說明

 

一個負責管理資料庫的朋友來找筆者,說負責的一個資料庫在啟動時候報錯,檔案找不到。具體日誌如下:

 

 

Lost write protection disabled

Completed: alter database mount exclusive

alter database open

Errors in file d:\app\administrator\diag\rdbms\DGT\DGT\trace\DGT_ora_2028.trc:

ORA-01113:檔案28需要介質恢復

ORA-01110: 資料檔案 28: 'F:\XXX\XXXX01.DBF'

ORA-1113 signalled during: alter database open...

Wed Sep 21 13:20:57 2016

Checker run found 51 new persistent data failures

 

 

環境是虛擬機器,朋友同時也是虛擬平臺管理員,平時對硬碟故障監控的比較勤。資料庫是11gR2,具體版本為11.2.0.1 For Windows版本。遠端登入作業系統,對應的各個磁碟機代號都存在,而且正常訪問。

 

出現問題的F盤檔案,也可以從資源管理器中找到。

 

遇到這種情況,作為分析人員,不是簡單去重複重啟伺服器,這樣通常會讓問題更加惡化。這個時候,DBA首要工作是“手離開鍵盤,通知可以幫助你的領導和同事”!大家一起坐下來,透過分析來確認問題源頭。

 

 

注意:分析的過程中,不能單方面聽取管理員和使用者的陳述,因為在高壓力的情況下,管理員可能會將重要的操作、現象加以迴避。所以,alert log、作業系統日誌和應用伺服器日誌都是可以忠實反映問題的資料來源。下面是透過多方面驗證得到的故障分析:

 

ü  問題源頭是虛擬化平臺備份軟體故障,在對伺服器進行備份失敗的時候,生成的瞬時映象是不能自動刪除,長期留待系統中佔據空間;

ü  出現故障的伺服器恰恰是本次軟體故障受影響的伺服器之一,資料量超過1T

ü  故障資料庫在關閉修理之前,朋友曾經shutdown immediate關機,當時操作正常,沒有報錯;

ü  該伺服器在啟動過程中,獨立的各個磁碟機代號分別對應了不同的磁碟組,備份軟體廠商曾經進行過處理;

ü  該資料庫中資料輸入資料倉儲型別系統,目前資料已經載入完畢,近幾個月都是進行只讀操作;

ü  資料庫處在非歸檔情況下,無備份;

 

2、問題分析

 

正常情況下,無備份、非歸檔情況下的Oracle系統,一旦發生檔案損壞、資料丟失的情況,都屬於是大事故。很多時候,能修復都是依賴一些特定條件和好運氣。針對這個案例,筆者認為一個基本出發點就是之前的“成功關閉”。

 

Oracle關閉系統有若干種模式,如shutdown abortnormalimmediatetransactional。每種關閉模式都對應不同的行為,shutdown immediate操作是可以保證各個檔案檔案頭SCN和控制檔案control fileSCN一致。在這個問題中,也可以在alert log中找到對應的過程記錄。

 

那麼,為什麼在重新啟動伺服器和Oracle之後,出現了丟失檔案的現象。曾經一致的SCN出現了什麼問題。

 

這個時候,一種比較方便的是觀察檢視v$datafilev$datafile_header兩個物件。v$datafile是在控制檔案中記錄的各個檔案的SCN和對應資訊,而v$datafile_header是各個資料檔案對應的檔案頭資訊。透過對比,檢視發現一些端倪。

 

 

SQL> select a.name,a.checkpoint_change# start_SCN,

  2     b.checkpoint_change# last_SCN

  3      from v$datafile_header a, v$datafile b

  4    where a.file#=b.file#;

 

NAME                           START_SCN   LAST_SCN

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

D:\APP\ADMINISTRATOR\ORADATA\DGT\SYSTEM01.DBF     1490874094 1490874094

(篇幅原因,有省略……

 

E:\DATAFILE\DATA1G17.DBF       1490874094 1490874094

E:\DATAFILE\DATA1G18.DBF       1490874094 1490874094

F:\XXX\XXXX01.DBF       1490736502 1490874094

F:\XXX\XXXX02.DBF       1490736502 1490874094

F:\XXX\XXXX03.DBF       1490736502 1490874094

F:\XXX\XXXX04.DBF       1490736502 1490874094

(篇幅原因,有省略……

F:\FINISH\FINISH23.DBF       1490736502 1490874094

E:\DATAFILE\DATA1G21.DBF       1490874094 1490874094

 

82 rows selected

 

SQL> select checkpoint_change# from v$database;

 

CHECKPOINT_CHANGE#

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

        1490874094

 

 

注意:這個資料庫對應的檔案數量是比較多的,為82個。出現問題的是F盤所有檔案的檔案頭SCN和控制檔案SCN有比較大的差異,其他檔案沒有差異。

 

檢索兩個SCN號:1490874094對應的時間是2016/9/21 9:49,而1490736502對應的時間是2016/9/20 9:00。顯然是檔案在關閉shutdown immediate之後,由於一些原因被替換為24小時之前的檔案。

 

和朋友確認,的確是有可能備份廠商為了能夠啟動資料庫,似乎使用過頭一天的映象來部分還原資料檔案,而且是整個F盤。

 

瞭解了原有,就起碼有一個基本出發點。下面就是如何進行資料處理,具體來說有三種方法可以考慮:

 

ü  如果需要緊急的啟動資料庫,在非歸檔模式下,可以將F盤對應的表空間和資料檔案offline drop剔除資料庫。但是這樣,就永遠不能將檔案資料追回了;

ü  對應F盤上的資料都是資料表空間檔案,而不是系統表空間,而且在一天中乜有對應的更新,所以可以透過bbed型別手工修改檔案頭SCN編號,讓所有檔案SCN號統一。這樣就可以避免open過程錯誤,但是需要人為修改若干個檔案頭,技術風險存在;

ü  第三種是讓Oracle啟動open過程放棄驗證SCN一致性,強行開啟系統。這樣的問題是,後續也可能出現其他報錯問題。

 

經過討論,決定使用第三種方法進行操作。

 

3、操作處理

 

Oracle放棄一致性檢查的引數是_ALLOW_RESETLOGS_CORRUPTION,將其新增在pfile中,使用這個pfile啟動資料庫。

 

注意:放棄驗證之後,依然會有open resetlog方式啟動資料庫,重新整理全體SCN物件的情況。之後,open狀態依然存在問題。

 

 

SQL> alter database open;

alter database open

*

1 行出現錯誤:

ORA-01092: ORACLE instance terminated. Disconnection forced

ORA-00704: bootstrap process failure

ORA-00704: bootstrap process failure

ORA-00604: error occurred at recursive SQL level 1

ORA-01555: snapshot too old: rollback segment number 6 with name

"_SYSSMU6_1439239625$" too small

程式 ID: 2596

會話 ID: 96 序列號: 1

 

 

alert log中,報錯如下:

 

 

Thu Oct 06 10:04:19 2016

SMON: enabling cache recovery

ORA-01555 caused by SQL statement below (SQL ID: 4krwuz0ctqxdt, SCN: 0x0000.58dbbfec):

select ctime, mtime, stime from obj$ where obj# = :1

Errors in file d:\app\administrator\diag\rdbms\DGT\DGT\trace\DGT_ora_7856.trc:

ORA-00704: 載入程式程式失敗

ORA-00704: 載入程式程式失敗

ORA-00604: 遞迴 SQL 級別 1 出現錯誤

ORA-01555: 快照過舊: 回退段號 6 (名稱為 "_SYSSMU6_1439239625$") 過小

Errors in file d:\app\administrator\diag\rdbms\DGT\DGT\trace\DGT_ora_7856.trc:

ORA-00704: 載入程式程式失敗

ORA-00704: 載入程式程式失敗

ORA-00604: 遞迴 SQL 級別 1 出現錯誤

ORA-01555: 快照過舊: 回退段號 6 (名稱為 "_SYSSMU6_1439239625$") 過小

Error 704 happened during db open, shutting down database

USER (ospid: 7856): terminating the instance due to error 704

Instance terminated by USER, pid = 7856

ORA-1092 signalled during: alter database open...

opiodr aborting process unknown ospid (7856) as a result of ORA-1092

Thu Oct 06 10:04:21 2016

ORA-1092 : opitsk aborting process

 

 

Oracle啟動open階段要進行兩個recovery,分別為Media RecoveryCache RecoveryMedia Recovery主要是基於online redo log進行日誌的前滾操作,Cache Recovery則是依賴從bootstrap$等系列資料字典物件建立重構,將資料庫啟動的操作過程。

 

當前報錯主要是在執行SQL4krwuz0ctqxdt的時候,要求SCN0x0000.58dbbfec的資料映象。這個SCN時間對應為:1490796524,而檢索時候希望使用MVCC特性,就出現了undo段不支援的情況了。

 

那麼,這個時間點是什麼?

 

 

 

SQL> select a.name,a.checkpoint_change# start_SCN,

  2     b.checkpoint_change# last_SCN

  3      from v$datafile_header a, v$datafile b

  4    where a.file#=b.file#;

 

NAME                         START_SCN   LAST_SCN

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

D:\APP\ADMINISTRATOR\ORADATA\DGT\SYSTEM01.DBF  1490776516 1490776516

D:\APP\ADMINISTRATOR\ORADATA\DGT\SYSAUX01.DBF   1490776516 1490776516

 

SQL> select resetlogs_change#, CHECKPOINT_CHANGE# from v$database;

 

RESETLOGS_CHANGE# CHECKPOINT_CHANGE#

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

       1490736503         1490776516

 

 

由於原來的SCN比較高,現在檢索一個過去的SCN時間點是不存在的。解決的方法是強制的推動SCN到一個適當地時間點。

 

 

 

SQL> conn / as sysdba

已連線。

SQL> select open_mode from v$database;

 

OPEN_MODE

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

MOUNTED

 

 

SQL> alter session set events '10015 trace name adjust_scn level 10';

 

會話已更改。

 

SQL> select CHECKPOINT_CHANGE# from v$database;

 

CHECKPOINT_CHANGE#

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

        1490796521

 

SQL>

 

SQL> alter session set events '10015 trace name adjust_scn level 10';

 

會話已更改。

 

SQL> select CHECKPOINT_CHANGE# from v$database;

 

CHECKPOINT_CHANGE#

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

        1490796521

 

SQL> alter session set events '10015 trace name adjust_scn level 10';

 

會話已更改。

 

SQL> select CHECKPOINT_CHANGE# from v$database;

 

CHECKPOINT_CHANGE#

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

        1490796521

 

SQL> alter database open;

 

資料庫已更改。

 

SQL> select CHECKPOINT_CHANGE# from v$database;

 

CHECKPOINT_CHANGE#

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

        1490816526

 

 

注意:當前資料庫版本為11.2.0.1,透過10015方法推動SCN編號前進的策略是可以的。之後的11.2.0.211.2.0.3之後,這種方法就被Oracle禁用了,只能使用oradebug來改寫記憶體進行修改了。

 

推動Oracle SCN編號之後,Oracle可以正常啟動開啟,問題消失。

 

4、結論

 

Oracle故障是我們經常遇到的問題,每一種故障的處理方法都有所不同。處理的過程,是建立在我們大量的分析思考基礎上,從資料安全留存的角度出發進行的最優決策。


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

相關文章