數據恢複:一則強行關庫引發的蝴蝶效應
李真旭(Roger)
ACOUG 核心專家,Oracle ACE,雲和恩墨技術專家
這是某網友的維護的一套數據庫,據說是正常重啟之後就無法啟動數據庫了。那麼我們先來看看日誌是什麼樣的:
我們可以看到,節點1在9:48:52秒被強行終止重啟了實例。而且我們還可以看出該節點從9:42開始就出現ORA-27090 錯誤。而該錯誤通常跟操作係統有關係,通過後麵的Linux-x86_64 Error: 4: Interrupted system call 錯誤也驗證了這一點。
這裏我們無論是看節點1還是節點2的alert log日誌都會發現,由於smon進程在進程事務恢複時失敗之後,導致數據庫實例最終宕掉。宕掉之後就再也無法正常啟動了。很明顯這是強行關庫之後帶來的蝴蝶效應。
這裏我們來看看其中節點2的這個ORA-00600 [16559]是什麼含義?
從解釋來看,這是Oracle 數據字典表tab$出現了不一致的情況。比較鬱悶的是,客戶的dataguard也壞掉了,也是一樣的錯誤。那麼看來隻能進行恢複了。這裏首先要明白,節點1的ora-00600 [16703]本質上來講跟ora-00600 [16559]是一回事。
從具體的錯誤來看,Oracle在open時,進行bootstrap初始化的過程就失敗了,因此報錯ORA-00704: bootstrap process failure.處理思路也很簡單,我們首先通過10046 trace跟蹤open的過程,來看看Oracle 在bootstrap初始化的時候在進行什麼操作時報錯的?
從上麵的錯誤不難看出就是在訪問tab$ 的時候報錯的,而且是訪問的obj#=20的這個對象。那麼這個對象是什麼呢?
根據我們的查詢以及對ORA-00600 [16703],[1403],[20] 這個錯誤的理解,那麼我這裏可以大致判斷這個錯誤後的幾個數字的含義:
16703: 錯誤代碼,表示數據字典基表存在不一致
1403: 表示數據沒找到或者不匹配,即not data found.
20: 表示訪問的對象號,即object_id.
同時我們從前麵的10046 trace跟蹤來看,報錯的SQL語句訪問了3個block,然後報錯,分別是file 1 block 50,51,26。
這我們分別dump 上麵的3個block發現其中block 51,26 的dump 內容如下:
block 51
block 26
看到這裏,我就想是否可以通過bbed先把這2個block 給修複了,看看是否能夠起來。如下是簡單的修複過程:
對於51號block 由於是Index 修改非常簡單,這裏不多說。26號block 是cluster table,這個相對複雜的多。首先提交事務、修改lock flag之後verify還是報錯,如下:
這裏繼續修改聚簇對應的kdbr信息(這裏以其中一個kdbr為例):
我們經過幾處簡單修改之後,再次verify校驗已經不再報錯了;不過再次open數據庫時,發現報另外一個錯誤了:
從錯誤來看,bootstrap的初始化過程仍然有問題。通過10046 trace跟蹤發現還是那幾個block。回想前麵這個block的dump時,看到的幾行操作是delete,如下:
tl: 4 fb: -CHDFL– lb: 0×2 cc: 0 cki: 0
那麼我們這裏試做將這幾個被刪除的操作進行還原是否ok 呢? 也就是用bbed來恢複這7個delete操作。
由於是cluster table 的block,操作相對麻煩一些。不過我嚐試修改之後,最後發現錯誤仍然一樣。其中[kdoirp-3]是什麼含義呢? 我們來看下Oracle 文檔的描述:
很明顯,這表示insert row piece。 看來我們單純的修改這2個block 並不能繞過這個問題。 實際上後麵我dump分析發現又涉及到_next_object,又將問題複雜化了。
雖然我相信多折騰幾次可以解決這個問題。但是操作確實麻煩,費勁。不過此時通過之前的備份restore出來的system文件已經ok了。這裏我用bbed 將涉及到的幾個block 進行替換,最後再修改resetlogs信息,重建控製文件之後,進行recover。非常順利的打開了數據庫。
最後檢查alert log 還涉及到smon 回滾某個事務失敗。那麼如何完美處理呢?
首先dump undo header,然後獲取該事務涉及的操作對象,然後使用參數屏蔽回滾段後,將undo表空間重建即可。
針對涉及到的對象,由於破壞了事務的完整性,那麼建議對表進行分析,其中Index進行重建。
----the end
本文出自數據和雲公眾號,原文鏈接
最後更新:2017-07-17 17:33:28