BAD Block 壞塊的處理

liypsky發表於2010-12-14

一.壞塊的發現
----------------------------------------------------
1.檢查整個資料庫中所有表,可以利用Exp工具匯出整個資料庫,
 存在缺陷:
a.HWM以上的壞塊不會發現;
b.索引中存在的壞塊不會發現;
c.資料字典中的壞塊不會了現;

2.比較重要表做壞塊檢查,可以使用ANALYZE TABLE tablename VALIDATE STRUCTURE CASCADE
執行了壞塊檢查,但不會標記為corrupt,檢測的結果儲存在USER_DUMP_DEST目錄下的使用者trace檔案中.

3.Oracle專門工具DBV來檢查壞塊

[@more@]關鍵字 說明 (預設)
----------------------------------------------------
FILE 要驗證的檔案 (NONE)
START 起始區塊 (檔案第一個區塊)
END 結束區塊 (檔案最後的區塊)
BLOCKSIZE 邏輯區塊大小 (8192)
LOGFILE 輸出日誌 (NONE)
FEEDBACK 顯示進度 (0)
PARFILE 引數檔 (NONE)
USERID 使用者名稱/密碼 (NONE)
SEGMENT_ID 區段 ID (tsn.relfile.block) (NONE)
HIGH_SCN 要驗證的最高區塊 SCN (NONE)
(scn_wrap.scn_base OR scn)

例:
E:oracleproduct>dbv file=SBD01.dbf

DBVERIFY: Release 10.2.0.1.0 - Production on 星期二 12月 14 14:27:53 2010
Copyright (c) 1982, 2005, Oracle. All rights reserved.
DBVERIFY - 驗證開始 : FILE = SBD01.dbf

DBVERIFY - 驗證結束
檢查總頁數 : 12800
處理總頁數 (資料) : 65
失敗總頁數 (資料) : 0
處理總頁數 (索引) : 47
失敗總頁數 (索引) : 0
已處理過的總頁數 (其他): 219
總共處理的頁數 (區段) : 0
總共失敗的頁數 (區段): 0
空的總頁數 : 12469
標記為損毀的總頁數 : 0
匯集總頁數 : 0
最高區塊 SCN : 1094832 (0.1094832)

二.壞塊發現後的處理:
-------------------------------------------------
1. 先收集相應的關於壞塊的資訊,從AlertSID.log檔案或者從trace檔案中查詢,
例如以下的一些資訊:
Ora-1578 file# (RFN) block#
Ora-1110 file# (AFN) block#
Ora-600 file# (AFN) block#

其中RFN表示的是relative_fno
AFN表示的是file_id
Select file_name,tablespace_name,file_id ,relative_fno “RFN”
From dba_data_files
Union All
Select file_name,tablespace_name,file_id, relative_fno“RFN”
From dba_temp_files;

2. 確定存在壞塊的物件是什麼:
SELECT tablespace_name,segment_type,owner,segment_name, partition_name
FROM dba_extents
WHERE file_id =
AND between block_id AND block_id + blocks – 1;
透過上面這個查詢語句就可以查出當前存在壞塊的物件是什麼,是什麼型別的物件。需要注意的是如果是temp檔案中出現壞塊,是沒有記錄返回的。

3. 根據2中查詢出來的物件型別,確定相應的處理方法
出現壞塊的常見物件有:
 Sys使用者下的物件
 回滾段
 臨時段
 索引或者分割槽索引
 表
常用的處理方法有:
 恢復資料檔案
 只恢復壞的block(9i以上版本可用)
 透過ROWID RANGE SCAN 儲存資料
 使用DBMS_REPAIR
 使用EVENT
4. 具體處理方法的介紹
 恢復資料檔案方法:
如果資料庫是歸檔方式下,並且有完整的物理備份,就可以使用此方法來恢復。
步驟如下:
1) 先offline受影響的資料檔案,執行以下的語句:
ALTER DATABASE DATAFILE ‘name_file’ OFFLINE;

2) 保留有壞塊的資料檔案,然後複製備份的資料檔案。如果恢復的資料檔案要求路徑不同,執行以下的語句:
ALTER DATABASE RENAME FILE ‘old_name’ TO ‘new_name’;

3) 恢復資料檔案,執行以下語句:
RECOVER DATAFILE ‘name_of_file’;

4) Online恢復後的資料檔案,執行以下的語句:
ALTER DATABASE DATAFILE ‘name_of_file’ ONLINE;

 只恢復壞的block(9i以上版本可用)
使用這種方法要求資料庫版本是9.2.0以上,要求配置了Rman的catalog資料庫,資料庫為歸檔方式,並且有完整的物理備份。

步驟如下:
使用RMAN的BLOCKRECOVER命令 :
Rman>run{blockrecover datafile 5 block 11,16;}

也可以強制使用某個SCN號之前的備份,恢復資料塊。
Rman>run{blockrecover datafile 5 block 11,16 restore until sequence 8505;}

 透過ROWID RANGE SCAN 儲存資料
1) 先取得壞塊中ROW ID的最小值,執行以下的語句:
SELECT dbms_rowid.rowid_create(1,,,0) from DUAL;

2)取得壞塊中的ROW ID的最大值,執行以下的語句:
SELECT dbms_rowid.rowid_create(1,,,,0) from DUAL;

3)建立一個臨時表儲存那些沒有壞塊的資料,執行以下的語句:
CREATE TABLE salvage_table AS SELECT * FROM corrupt_tab Where 1=2;

4)儲存那些不存在壞塊的資料到臨時表中,執行以下的語句:
INSERT INTO salvage_table SELECT /*+ ROWID(A) */ * FROM A WHERE rowid < ‘’;
INSERT INTO salvage_table SELECT /*+ ROWID(A) */ * FROM A WHERE rowid >= ‘’;

5) 根據臨時表中的資料重建表,重建表上的索引,限制。

 使用10231診斷事件,在做全表掃描的時候跳過壞塊

1) 可以在session級別設定:

ALTER SESSION SET EVENTS ‘10231 TRACE NAME CONTEXT FOREVER, LEVEL 10′;

也可以在資料庫級別上設定:
在初始化引數中加入:event=”10231 trace name context forever, level 10″,然後重啟資料庫。

2) 然後從存在壞塊的表中取出不存在壞塊的資料,執行以下的語句:
CREATE TABLE salvage_emp AS SELECT * FROM corrupt_table;

3) 最後rename生成的corrupt_table為原來表的名字,並重建表上的索引和限制。

 使用dbms_repair包進行恢復(待測試)
使用dbms_repair標記有壞塊的表,在做全表掃描的時候跳過壞塊,執行以下的語句:

Execute DBMS_REPAIR.SKIP_CORRUPT_BLOCKS(’’,'’);

然後使用exp工具或者createtable as select的方法取出沒有壞塊資料,然後重建表,表上的索引和限制。

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

相關文章