數據恢復利用構造ROWID實現無備份情況下繞過ORA-1578、ORA-8103、ORA-1410等邏輯/物理壞塊問題
簡單來說ORA-8103 的主要成因有2類:
數據塊的 block type 類型 是 無效的 或者讀出來的塊類型與Oracle期望的不壹致。 例如 Oracle 認為該數據塊的類型為data(type=6),但實際卻不是。
數據塊中的data_object_id 和 數據字典中的data_object_id不匹配
針對ORA-8103問題 我們優先推薦壹些措施:
ORA-08103問題的診斷最好是能生成8103錯誤的ERROR STACK TRACE, 在TRACE中會記錄具體引發8103的對象的OBJ和OBJD,這便於我們定位可能存在corruption的對象。
問題在於往往前臺進程遇到ORA-08103錯誤不會在後臺生成TRACE文件,這需要我們手動設置8103 觸發ERRORSTACK的EVENTS:
ALTER SYSTEM SET EVENTS ’8103 TRACE NAME ERRORSTACK LEVEL 3′;
解決思路包括:
1. 通過OBJD和DBA定位到具體的表名和塊號
2. 有條件的情況下對該表做壹個analyze .. validate structure
3. 有條件的情況下對該表所在tablespace做壹個 dbms_space_admin.ASSM_TABLESPACE_VERIFY
4. 有條件的情況下move這張表或者相關的分區,嘗試繞過該問題
5. 有條件的情況下降該表或分區移動到MSSM表空間上,繞過該問題
execute dbms_space_admin.tablespace_verify(‘&tablespace_name’)
oradebug setmypid
oradebug tracefile_name
execute dbms_space_admin.assm_tablespace_verify(‘&tablespace_name’,dbms_space_admin.TS_VERIFY_BITMAPS)
oradebug setmypid
oradebug tracefile_name
針對不同的 analyze validate structure 後得到的結果 , 我們可以得到壹些初步的結論:
如果執行 flush buffer cache之後再次analyze validate structure不再報ORA-8103錯誤則說明:
可能是完全正常的現象,之前的ORA-8103正是也因為對象正在被DROP/TRUNCATE而導致SELECT報ORA-8103。壹般來說Call Stack會顯示進程正嘗試訪問該段的segment header。 更多信息可以參考BUG 7441661
也可能該問題僅僅發生在buffer cache層,而沒有發生在DISK上。通過flush buffer_cache若能解決,則壹般是這種情況,往往是Buffer Cache管理的BUG 。
如果執行 flush buffer cache之後再次analyze validate structure再次報ORA-8103錯誤則說明:
如果dump對應的數據塊發現 該塊在邏輯上是完整壹致的(也可以用bbed/dbv工具驗證), 則有可能是Lost Write,則不是被其他對象重格式化使用了。
這裏判斷Lost Write的壹個重要手段是 對塊做recover/blockrecover,如果recover能修復該塊,則說明是因為Lost Write引起了本ORA-8103問題,如果不是則說明99%的可能性是BUG引起的。
常見的壹種現象是 使用第三方工具在數據庫打開的情況下copy 數據庫,這些工具的BUG可能導致copy 老的版本的block到目標新庫中。
另壹種可能是 extent盤區級別的不壹致。 同壹個數據塊/extent 可能 同時屬於 2個數據段segment,這導致其中的壹個被後者覆蓋。 通過recover的方式是無法修復這種場景的, 因為這種邏輯的訛誤發生在表空間級別的extent信息上。 可以檢查dba_extents/dba_segments/dba_free_space這些視圖來確定問題數據塊到底是否同時屬於多個對象, 或者 壹個數據塊 同時出現在dba_extents/dba_segments/dba_free_space 三個視圖中, 因為 used extent 不該出現在dba_free_space中,而free extent不該在dba_extents,當然要排除recyclebin中對象的影響。 絕大多數情況下這種extent邏輯不壹致的現象, 被稱作extent overlap , 通常是Oracle Space Management空間管理層面的BUG。
在對ORA-8103問題的診斷過程中 定位問題的OBJD異常重要。應當說準確地將ORA-8103錯誤與BUG定位起來是有難度的,因為這往往需要涉及到redo dump以發現到底是哪些opcode造成了後續的objd 或 block type 不壹致。在壹些BUG中我們發現,由於可能的變量陳舊,造成objd的結構未合理清除, 之後就發現block上的objd是錯的了,可能遇到ORA-8103也可能是ORA-1410, 這引起了後續其他的邏輯訛誤,以至於很難通過TRACE/REDO LOG DUMP來定位原始問題所在。 這也是為什麽雖然在例如版本10.2.0.4上有幾個ORA-8103的bug Note, 但這些BUG最終未被close為real software bug即真的軟件BUG , 大多都是不了了之,因為在用戶現場的TRACE和REDO DUMP都未必能真實定位到問題所在,這也是為什麽我們要說邏輯訛誤的分析和處理原要比物理訛誤來的復雜。
Maclean的經驗是 在有大量Oracle DB的環境下 壹年出個幾次的邏輯/物理壞塊是很正常的事情, 對於物理訛誤 我們只要切實備份即可99%得解決。 而對於邏輯壞塊可做的 事情不多, 打最新的補丁 開 db_block_checking、db_block_checksum幾件事情而已。
值得壹說的是 如果去讀壹下ORA-8103的壹些Bug Note,可以發現使用 LOB、APPEND INSERT、PARALLEL INSERT、exchange partition 、Split partition、advanced compression、HCC 混合列壓縮往往是引起ORA-8103的高危操作 , 但實際我們又不可能放棄上述操作。
如果自己搞不定可以找ASKMACLEAN專業數據庫修復團隊成員幫您恢復!