閱讀317 返回首頁    go 阿裏雲 go 技術社區[雲棲]


數據恢複:一則強行關庫引發的蝴蝶效應

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

李真旭(Roger)

ACOUG 核心專家,Oracle ACE,雲和恩墨技術專家


這是某網友的維護的一套數據庫,據說是正常重啟之後就無法啟動數據庫了。那麼我們先來看看日誌是什麼樣的:

640?wx_fmt=png&wxfrom=5&wx_lazy=1


我們可以看到,節點1在9:48:52秒被強行終止重啟了實例。而且我們還可以看出該節點從9:42開始就出現ORA-27090 錯誤。而該錯誤通常跟操作係統有關係,通過後麵的Linux-x86_64 Error: 4: Interrupted system call 錯誤也驗證了這一點。640?wx_fmt=png&wxfrom=5&wx_lazy=1

640?wx_fmt=png&wxfrom=5&wx_lazy=1

640?wx_fmt=png&wxfrom=5&wx_lazy=1


這裏我們無論是看節點1還是節點2的alert log日誌都會發現,由於smon進程在進程事務恢複時失敗之後,導致數據庫實例最終宕掉。宕掉之後就再也無法正常啟動了。很明顯這是強行關庫之後帶來的蝴蝶效應。


這裏我們來看看其中節點2的這個ORA-00600 [16559]是什麼含義?

640?wx_fmt=png&wxfrom=5&wx_lazy=1


從解釋來看,這是Oracle 數據字典表tab$出現了不一致的情況。比較鬱悶的是,客戶的dataguard也壞掉了,也是一樣的錯誤。那麼看來隻能進行恢複了。這裏首先要明白,節點1的ora-00600 [16703]本質上來講跟ora-00600 [16559]是一回事。


從具體的錯誤來看,Oracle在open時,進行bootstrap初始化的過程就失敗了,因此報錯ORA-00704: bootstrap process failure.處理思路也很簡單,我們首先通過10046 trace跟蹤open的過程,來看看Oracle 在bootstrap初始化的時候在進行什麼操作時報錯的?

640?wx_fmt=png&wxfrom=5&wx_lazy=1


從上麵的錯誤不難看出就是在訪問tab$ 的時候報錯的,而且是訪問的obj#=20的這個對象。那麼這個對象是什麼呢?

640?wx_fmt=png&wxfrom=5&wx_lazy=1


根據我們的查詢以及對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

640?wx_fmt=png&wxfrom=5&wx_lazy=1


block 26

640?wx_fmt=png&wxfrom=5&wx_lazy=1

640?wx_fmt=png&wxfrom=5&wx_lazy=1

看到這裏,我就想是否可以通過bbed先把這2個block 給修複了,看看是否能夠起來。如下是簡單的修複過程:


對於51號block 由於是Index 修改非常簡單,這裏不多說。26號block 是cluster table,這個相對複雜的多。首先提交事務、修改lock flag之後verify還是報錯,如下:

640?wx_fmt=png&wxfrom=5&wx_lazy=1


這裏繼續修改聚簇對應的kdbr信息(這裏以其中一個kdbr為例):

640?wx_fmt=png&wxfrom=5&wx_lazy=1

640?wx_fmt=png&wxfrom=5&wx_lazy=1

640?wx_fmt=png&wxfrom=5&wx_lazy=1


我們經過幾處簡單修改之後,再次verify校驗已經不再報錯了;不過再次open數據庫時,發現報另外一個錯誤了:

640?wx_fmt=png&wxfrom=5&wx_lazy=1


從錯誤來看,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 文檔的描述:

640?wx_fmt=png&wxfrom=5&wx_lazy=1


很明顯,這表示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

  上一篇:go  DBA生存警示:係統級誤刪除案例及防範建議
  下一篇:go  自相矛盾:一個進程可以自成死鎖麼?