使用DBMS_REPAIR包修復壞塊(一)
?
??? 今天來學習一下數據壞塊的檢測和修復。Oracle為了檢測和糾正數據塊隨壞,提供了不同的方法,糾正方法有很多,第一是在檢測到損壞之后,就刪除并重建該對象,但是這個方法有時是不可用的,而且效果也不理想。如果數據塊損壞局限于行的子集,則可以選取除了損壞行之外的所有行來重建表。
第二個方法是使用DBMS_REPAIR包來檢測和修復表或索引中的損壞數據塊。這個方法的好處在于可以確定損壞出現的位置,并重建或修復它們,使對象可以繼續使用。
?
??? 需要注意的是:任何包含數據丟失的損壞都需要分析和理解數據是如何填充進整個數據庫系統中的。所以DBMS_REPAIR的修復方法并不一定適用于每個損壞問題,基于損壞的本質,是有可能丟失數據或引入邏輯矛盾的,因此在使用DBMS_REPAIR修復時要權衡其帶來的得失利弊。
?
?
??? 首先介紹一下DBMS_REPAIR包(注意:這個包只能由sys用戶查看、使用):
?
CREATE OR REPLACE PACKAGE dbms_repair
?
? IS
? ----------------------------------
? --? OVERVIEW
? --
? --? The DBMS_REPAIR package consists of data corruption repair procedures
? --
? --? SECURITY
? --
? --? The package is owned by SYS.
? --? Execution privilege is not granted to other users.
? ----------------------------------
? --
? --? ENUMERATION TYPES:
? --
? --? Object Type Specification
? --
? TABLE_OBJECT constant binary_integer := 1;
? INDEX_OBJECT constant binary_integer := 2;
? CLUSTER_OBJECT constant binary_integer := 4;
?
? --
? -- Flags Specification
? --
? SKIP_FLAG??? constant binary_integer := 1;
? NOSKIP_FLAG? constant binary_integer := 2;
?
? --
? -- Admin Action Specification
? --
? CREATE_ACTION constant binary_integer := 1;
? PURGE_ACTION? constant binary_integer := 2;
? DROP_ACTION?? constant binary_integer := 3;
?
? --
? -- Admin Table Type Specification
? --
? REPAIR_TABLE constant binary_integer :=1;
? ORPHAN_TABLE constant binary_integer :=2;
?
? --
? -- Object Id Specification
? --
? ALL_INDEX_ID constant binary_integer :=0;
?
? --
? -- Lock Wait Specification
? --
? LOCK_NOWAIT constant binary_integer := 0;
? LOCK_WAIT?? constant binary_integer := 1;
? -----------------------------------
? --
? -- PROCEDURES AND FUNCTIONS
? --
? --
?
? --
? -- NOTE: default table_name will be 'REPAIR_TABLE' when table_type is
? -- REPAIR_TABLE, and will be 'ORPHAN_KEY_TABLE' when table_type is
? -- ORPHAN_TABLE
? procedure admin_tables(
??? table_name IN varchar2 DEFAULT 'GENERATE_DEFAULT_TABLE_NAME',
??? table_type IN binary_integer,
??? action IN binary_integer,
??? tablespace IN varchar2 DEFAULT NULL);
? --admin_tables用于修復或隔離鍵表的管理函數(創建、刪除、凈化)
?
? --
? procedure check_object(
??? schema_name IN varchar2,
??? object_name IN varchar2,
??? partition_name IN varchar2 DEFAULT NULL,
??? object_type IN binary_integer DEFAULT TABLE_OBJECT,
??? repair_table_name IN varchar2 DEFAULT 'REPAIR_TABLE',
??? flags IN binary_integer DEFAULT NULL,
??? relative_fno IN binary_integer DEFAULT NULL,
??? block_start IN binary_integer DEFAULT NULL,
??? block_end IN binary_integer DEFAULT NULL,
??? corrupt_count OUT binary_integer);
? --check_object用于檢測和報告表中或索引中的損壞
?
? --
? procedure dump_orphan_keys(
??? schema_name IN varchar2,
??? object_name IN varchar2,
??? partition_name IN varchar2 DEFAULT NULL,
??? object_type IN binary_integer DEFAULT INDEX_OBJECT,
??? repair_table_name IN varchar2 DEFAULT 'REPAIR_TABLE',
??? orphan_table_name IN varchar2 DEFAULT 'ORPHAN_KEY_TABLE',
??? flags IN binary_integer DEFAULT NULL,
??? key_count OUT binary_integer);
? --dump_orphan_keys報告指出損壞數據塊中的行的索引項(在一個孤立鍵表中)
?
? --
? procedure fix_corrupt_blocks(
??? schema_name IN varchar2,
??? object_name IN varchar2,
??? partition_name IN varchar2 DEFAULT NULL,
??? object_type IN binary_integer DEFAULT TABLE_OBJECT,
??? repair_table_name IN varchar2 DEFAULT 'REPAIR_TABLE',
??? flags IN binary_integer DEFAULT NULL,
??? fix_count OUT binary_integer);
? --fix_corrupt_blocks用于將被check_object標記出來的數據塊標記為軟件錯誤
?
? --
? procedure rebuild_freelists(
??? schema_name IN varchar2,
??? object_name IN varchar2,
??? partition_name IN varchar2 DEFAULT NULL,
??? object_type IN binary_integer DEFAULT TABLE_OBJECT);
? --rebuild_freelists用于重建對象的空閑列表
?
? --
? procedure skip_corrupt_blocks(
??? schema_name IN varchar2,
??? object_name IN varchar2,
??? object_type IN binary_integer DEFAULT TABLE_OBJECT,
??? flags IN binary_integer DEFAULT SKIP_FLAG);
? --skip_corrupt_blocks掃描或索引期間,忽略被標記為損壞的數據塊
? --不使用是遇到損壞塊會報錯:ORA-01578
?
? --
? procedure segment_fix_status(
??? segment_owner IN varchar2,
??? segment_name? IN varchar2,
??? segment_type?? IN binary_integer DEFAULT TABLE_OBJECT,
??? file_number??? IN binary_integer DEFAULT NULL,
??? block_number?? IN binary_integer DEFAULT NULL,
??? status_value?? IN binary_integer DEFAULT NULL,
??? partition_name IN varchar2 DEFAULT NULL);
? --segment_fix_status:當SEGMENT管理為AUTO時,提供確定位圖項的損壞狀態。
?
? --
? procedure rebuild_shc_index(
??? segment_owner? IN varchar2,
??? cluster_name?? IN varchar2);
?
? --
? function online_index_clean(
??? object_id????? IN binary_integer DEFAULT ALL_INDEX_ID,
??? wait_for_lock? IN binary_integer DEFAULT LOCK_WAIT)
??? return boolean;
? --?? Example Usage of online_index_clean:
? --?? DECLARE
? --???? isClean BOOLEAN;
? --?? BEGIN
? --
? --???? isClean := FALSE;
? --???? WHILE isClean=FALSE
? --???? LOOP
? --?????? isClean := DBMS_REPAIR.ONLINE_INDEX_CLEAN(DBMS_REPAIR.ALL_INDEX_ID,
? --???????????????????????????????????????????????? DBMS_REPAIR.LOCK_WAIT);
? --?????? DBMS_LOCK.SLEEP(10);
? --???? END LOOP;
? --
? --???? EXCEPTION
? --????? WHEN OTHERS THEN
? --????? RAISE;
? --?? END;
? --?? /
?
END dbms_repair;
?
?
??? DBMS_REPAIR的限制有以下幾點:
?
??? 1、支持具有LOB列、嵌入表、varray列的表,但忽略out of line columns
??? 2、SKIP_CORRUPT_BLOCKS和REBUILD_FREELISTS支持簇,但CHECK_OBJECT不支持簇
??? 3、不支持索引結構表和LOB索引
??? 4、DUMP_ORPHAN_KEYS過程不能用于位圖索引或基于函數的索引
??? 5、DUMP_ORPHAN_KEYS過程最多處理3950字節長的鍵
?
??? 下面開始從頭來說明檢測、修復壞塊的過程:
?
一、檢測和報告損壞
?
??? 這個過程不僅僅是指出數據塊出什么錯了,還要指出相關的修復方針。為了檢測損壞,除了DBMS_REPAIR之外,還有幾個其他不同的選擇:
?
??? 1、DBMS_REPAIR
?
??? 對一個指定的表、分區或索引執行數據塊檢查,用結果填充一個修復表。使用CHECK_OBJECT和ADMIN_TABLES兩個過程。
?
??? CHECK_OBJECT檢查和報告指定對象的數據塊損壞,與用于索引和表的ANALYZE...VALIDATE STRUCTURE語句相同,數據塊檢查是用于索引和數據塊的。CHECK_OBJECT不僅報告損壞,如果以后在該對象上運行FIX_CORRUPT_BLOCKS時,它還標識任何方位。通過將這些信息填充進修復表而使這些信息可用,必須先用ADMIN_TABLES過程創建修復表。(執行CHECK_OBJECT過程后,查詢修復表即可知道對象的損壞和修復方針)
?
??? 2、DB_VERIFY
?
??? 外部命令行工具,它在脫機數據庫上執行數據塊檢查,具體使用方法另詳。
?
??? 3、ANALYZE
?
??? 與VALIDATE STRUCTURE選項一起使用,確認索引、表或簇的結構完整性;檢查或確認表和索引是同步的。
?
??? ANALYZE TABLE ... VALIDATE STRUCTURE 語句校驗被分析對象的結構。如果Oracle成功地校驗了該結構,則返回一條確認消息,如果Oracle遇到了對象結構中的損壞,則返回一條錯誤消息。此時就應該刪除并重建該對象。
?
??? 4、DB_BLOCK_CHECKING
?
??? 當DB_BLOCK_CHECKING=TRUE時被執行。在實際被標記成損壞之前識別損壞的數據塊。當數據塊被修改是執行檢查。
?
?
------------------
??? 剩下關于如何操作和修復明天再學習。
?
?