Oracle資料庫壞塊簡析
壞塊介紹
Oracle資料庫壞塊是指在資料庫的一個或多個數據塊出現內容混亂的現象。正常的數據塊都有固定合法的內容格式,壞塊的出現,導致資料庫讀寫進程無法正常解析數據塊的內容,進而使資料庫進程報錯乃至掛起,並可能會導致整個資料庫實例出現異常。
壞塊產生的原因
Oracle壞塊產生的原因有很多種,大概分為如下幾類:
1. 硬體問題
內存故障,CPU模塊故障,存儲系統故障
2.操作系統異常
內核調用異常,系統BUG,I/O錯誤,內存或交換空間異常,非資料庫進程異常使用Oracle緩衝池
3. Oracle BUG
4. 異常斷電,異常停止服務,日常操作存儲的擴容等
當出現壞塊時,為找到根因,需要花費大量的人力與精力去分析排查,很可能有些場景是無法重現的。在生產環境上,需要儘快恢復系統的可用性,所以會破壞現場,所以分析根因起來更加困難。我們只能從日常的運維過程中,盡量的預防此事件發生。
壞塊表象
在出現Oracle壞塊時,我們經常會碰到以下錯誤:
1)ORA-01578錯誤
2)ORA-1110錯誤
3)ORA-00600錯誤
4)Trace文件中出現分析對象失敗
5)其它異常事件
壞塊檢驗
1)Oracle提供Recovery Manager工具,具備掃描文件檢查壞塊的功能
RMAN> BACKUP CHECK LOGICAL VALIDATE DATAFILE n ;
select * from V$DATABASE_BLOCK_CORRUPTION ;
可以檢查數據文件是否包含壞塊。
2)DBV工具檢查
註:因為dbv要求file後面跟的必須是一個文件擴展名,所以如果用裸設備存儲的,就必須使用ln鏈接裸設備到一個文件,然後再用dbv對這個鏈接文件進行檢查。
ANALYZE TABLE tablename VALIDATE STRUCTURE CASCADE
它執行壞塊的檢查,但是不會標記壞塊為corrupt,檢測的結果保存在USER_DUMP_DEST目錄下的用戶trace文件中。
3) exp工具導出整個資料庫可以檢測壞塊
但是以下情況的壞塊是檢測不出來的:
HWM以上的壞塊、索引中存在的壞塊、數據字典中的壞塊
壞塊處理
1)使用RMAN備份進行恢復
首先由上面的RMAN檢驗工具進行檢查,找出文件號與數據塊號,根據結果執行如下命令進行恢復:
RMAN>blockrecover datafile * block ** from backupset;
2)沒有備份的情況下(備份很重要啊,兄弟們)
採用exp導出命令,對報錯的表或者對象進行導出。
exp user/password file=bad.dmp tables=bad_table;
導出命令在執行中會報ORA-01578錯誤,會提示那個文件號的文件以及這個文件中的哪個塊被損壞,如:ORA—01578:ORACLE 數據塊損壞(文件號 30,塊號 31156)
查詢那些對象被損壞:
select tablespace_name,segment_type,owner,segment_name From dba_extents Where file_id=30 and 31152 between block_id and block_id+blocks-1;
如果被損壞的塊是索引,可以通過索引重建來解決;如果損壞的是數據,那麼恭喜,只能丟失了。
設置如下內部事件使得exp操作跳過壞塊。
alter session set events="10231 trace name context forever,level 10";
重新執行導出命令,導出相關的表,再刪除表後導入表數據進行重建。丟了就丟了吧。
3)使用bbed恢復
這個官方不做技術支持,你愛干就可以干,我也不會用。
4)使用dbms_repair來標記和跳過壞塊(網上大把介紹)
4.1)創建管理表:
SQL> exec DBMS_REPAIR.ADMIN_TABLES("REPAIR_TABLE",1,1,"USERS");
SQL> exec DBMS_REPAIR.ADMIN_TABLES("ORPHAN_TABLE",2,1,"USERS");
4.2)檢查壞塊:
Set serveroutput on;
DECLARE
BAD NUMBER;
BEGIN
DBMS_REPAIR.check_object (schema_name => "APPS",
object_name => "BAD_OBJECT",
corrupt_count => BAD);
DBMS_OUTPUT.put_line ( TO_CHAR (BAD));
END;
/
SELECT *FROM repair_table;
4.3) 定位壞塊:dbms_repair.fix_corrupt_blocks
DECLARE
BAD NUMBER;
BEGIN
DBMS_REPAIR.fix_corrupt_blocks (schema_name => "APPS",
object_name => "BAD_OBJECT",
fix_count => BAD);
DBMS_OUTPUT.put_line (a => TO_CHAR (BAD));
END;
/
4.4) 跳過壞塊:skip_corrupt_blocks
exec dbms_repair.skip_corrupt_blocks(schema_name => "APPS",object_name => "BAD_OBJECT",flags => 1);
總結:壞塊雖討厭,但是做好備份,做好預案,資料庫伺服器上別瞎整一些其它應用,定期升級打補丁,還是可以保住飯碗的。
---END---
TAG:應用DBA |