非常規方法,輕鬆應對Oracle資料庫危急異常

watershed發表於2016-04-09



相信很多Oracle DBA在職業生涯中或多或少都遇到過這樣的情況:資料檔案被誤刪了,儲存壞了無法識別資料檔案,最糟糕的是,竟然rman備份也是壞的…… 遇到問題凌亂慌張是沒用的,而貿然動手也是非常危險的,當遇到緊急問題,最重要的就是冷靜分析,臨危不亂。

 

下面我透過幾個實戰案例,給大家介紹幾例資料檔案異常可採用的非常規恢復方法。

 

一、資料檔案被刪除的恢復


實驗場景:由於維護人員的誤操作,導致資料庫部分資料檔案被刪除,資料庫報錯。

 

>>>>故障模擬


10點59分,誤操作刪除檔案。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

11點20分資料庫alert日誌顯示出現ora-01116等錯誤,根據後臺日誌顯示此時ts_test01.dbf檔案已經無法正常開啟。


非常規方法,輕鬆應對Oracle資料庫危急異常

 

但是資料庫沒有因此關閉,還處於read write狀態。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

>>>>問題分析


資料檔案被誤刪,資料庫仍然處於open狀態。對於此問題可以透過linux系統的“檔案描述符”找回丟失的資料檔案。在Linux系統中一切皆可以看成是檔案,檔案描述符(file descriptor)是核心為了高效管理已被開啟的檔案所建立的索引,所有執行I/O操作的系統呼叫都透過檔案描述符。檔案描述符開啟的檔案控制程式碼以及i-node的關係如圖:


非常規方法,輕鬆應對Oracle資料庫危急異常

在linux 系統中,資料檔案被刪除後,其檔案控制程式碼還被相關資料庫程式所開啟使用,可以透過該控制程式碼資訊直接複製將其恢復。需要注意的是,在此期間資料庫不能關閉。否則相關控制程式碼將被釋放,檔案就無法找回。

 

>>>>恢復步驟


嘗試透過oracle dbwr程式找到被誤刪除的檔案控制程式碼。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

當前的oracle dbwr程式的spid是3293 可以透過該程式找到丟失的ts_test01.dbf 檔案控制程式碼。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

含一些數字命名的目錄,它們是程式目錄,其下的fd子目錄包含程式相關的所有的檔案描述符。子本例中oracle的dbwr 程式的fd目錄下正有已經被刪除的ts_test01.dbf檔案的描述符(注:檔案描述符為25,當前的狀態是deleted)。


非常規方法,輕鬆應對Oracle資料庫危急異常

透過copy的方式恢復已刪除的資料檔案,並設定正確的屬組許可權。


非常規方法,輕鬆應對Oracle資料庫危急異常

非常規方法,輕鬆應對Oracle資料庫危急異常


透過將offline相關表空間並重置檔案路徑的方式完成檔案重定向。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

由於前期資料檔案無法open的問題,部分已更改的資料無法寫入資料檔案,導致datafile header 上的checkpoint#和controlfile檔案的checkpoint_change#不一致,需要對資料檔案進行介質恢復。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

進行介質恢復之後,表空間可以正常online,故障處理也算完成。

 

>>>>總結感悟


作為系統維護人員rm,mv均屬於高危操作,在執行之前一定要反覆思考,確定影響,做到“寧停3分,不搶1秒”。當遇到資料庫問題時,應維持故障現狀,在沒有清楚的瞭解問題原因以及解決方案之前,草率的行動將使問題複雜化,造成不可估量的損失。對於此案例,如果貿然的關閉資料庫,只能使用rman備份進行恢復,如果備份失效,資料丟失將不可避免。總之做到,臨危不亂!三思而行!

 

二、使用bbed跳過歸檔檔案的完全恢復

 

實驗場景:儲存損壞導致部分資料檔案損壞,需要使用備份進行還原,在資料庫恢復階段發現缺失部分歸檔,導致資料庫無法恢復,正常啟動。

 

>>>>實驗環境準備


使用rman 為資料庫做一個全備。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

對test表執行insert操作,每三次insert後執行一次switch logfile,保證生成的34,35,36三個歸檔各包含3條insert的操作日誌。


非常規方法,輕鬆應對Oracle資料庫危急異常
非常規方法,輕鬆應對Oracle資料庫危急異常


>>>>故障模擬


透過abort方式停庫後,刪除ts_test01.dbf 檔案模擬儲存故障。


非常規方法,輕鬆應對Oracle資料庫危急異常 

人為刪除sequence 35的歸檔日誌。至此,故障已經重現。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

當再次使用startup命令啟動時,資料庫在mount之後由於無法識別到datafile 6(ts_test01.dbf),最終只能停留在mount階段。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

透過rman 的方式進行資料檔案還原。在介質恢復階段rman報錯:no backup of archived log for thread 1 with sequence 35 and startingscn of…….。正是因為缺失了35號歸檔導致還原無法完成(35號歸檔已經被人為刪除)。

 

歸檔日誌按時間順序記錄著資料庫上的各類操作(包括insert,delete,update,create 等等)。歸檔的丟失意味著部分操作的缺失,oracle將無法繼續後續的歸檔檔案的恢復。

 

在此情況下使用常規手段顯然無法正常open資料庫。需要透過bbed跳過缺失的歸檔使其繼續完成介質恢復。

 

>>>>恢復步驟


透過rman的crosscheck archivelog all命令校驗歸檔日誌發現,缺少35號歸檔。


非常規方法,輕鬆應對Oracle資料庫危急異常


跳過缺失的歸檔需要將6號檔案的scn向前推進至少大於等於36號歸檔的first change#1243371


非常規方法,輕鬆應對Oracle資料庫危急異常
 

資料檔案的scn被記錄在檔案1號block偏移量484位元組開始的四個位元組中。當前6號檔案的scn經過大小端轉換之後十進位制的數值為1243327(dump的原值為bff81200經大小端轉換後的十六進位制為0012f8bf)。該值正好是35號歸檔的first change#


非常規方法,輕鬆應對Oracle資料庫危急異常
 

使用bbed更改資料檔案頭的scn號,使其變為1243381(注意更改的scn需要大於36號歸檔的first change#,在這次實驗中使用36號歸檔的first change#10作為新的scn號,經過十六進位制以及大小端轉換後資料為f5f812), 並使用sum apply 命令重新計算校驗和。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

要想跳過歸檔還需要資料檔案頭塊的rba。它由seq#、log block#、偏移量(固定為16)組成,決定了資料檔案從哪個歸檔日誌的哪個位置開始應用歸檔。Rba位於資料檔案頭塊偏移量500處開始連續的12個位元組(如圖從23開始到0000ffff結束,前4個位元組是日誌的序列號,中間4個位元組是日誌塊號,最後4個位元組是偏移量)。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

將rba修改為接下去的歸檔日誌.log block#.offset#(這次試驗rba被修改為24000000.02000000.10000000即36.2.16)


非常規方法,輕鬆應對Oracle資料庫危急異常
 

再次執行資料檔案6的介質恢復後資料庫可以正常開啟。由於跳過了部分日誌,免不了存在資料丟失或者不一致的問題。對於採用此方法恢復的資料庫建議在合適的時候停機重建。


非常規方法,輕鬆應對Oracle資料庫危急異常
 

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

相關文章