Decode360's Blog

          業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
          使用DBMS_REPAIR包修復(fù)壞塊(二)
          ?
          ??? 昨天簡單得了解了一下關(guān)于數(shù)據(jù)塊損壞后該如何操作,都是一些理論知識,當(dāng)然理論知識也還沒有學(xué)完 。今天來繼續(xù)學(xué)習(xí)理論知識,并且在完成之后找一個(gè)實(shí)例來實(shí)踐一下。好,下面開始。
          --------------------------------------
          ?
          ?
          二、評估使用DBMS_REPAIR的損益
          ?
          ??? 要判斷損益,需要了解一下問題:
          ?
          ??? 1、損壞的盤區(qū)是什么?
          ?
          ??? 這一步比較簡單,執(zhí)行CHECK_OBJECT過程,然后查詢修復(fù)表即可。
          ?
          ??? 2、其他可用于處理數(shù)據(jù)損壞的方法是什么?
          ?
          ??? 需要考慮以下幾種方法:
          ??? * 假設(shè)可以從另一數(shù)據(jù)源獲得數(shù)據(jù),則刪除、重建、并填充該對象。
          ??? * 對損壞的表發(fā)布CREATE TABLE ... AS SELECT語句,以重建新表
          ??? * 通過從選取(select)語句來排除損壞的行來忽略損壞
          ??? * 執(zhí)行介質(zhì)恢復(fù)
          ?
          ??? 3、當(dāng)使用DBMS_REPAIR來使一個(gè)對象可用時(shí),會引入什么邏輯矛盾或副作用?并考慮代價(jià)
          ?
          ??? 主要可能會有以下問題:
          ??? * 標(biāo)記損壞的數(shù)據(jù)塊中的行會無法訪問。
          ??? * 有可能破壞參照完整性約束,如有則需要停用
          ??? * 如果在表上定義了觸發(fā)器,要考慮如果刪除、重新插入數(shù)據(jù)是否會觸發(fā)
          ??? * 空閑列表數(shù)據(jù)塊可能不可訪問。
          ??????? 如果損壞數(shù)據(jù)塊在空閑列表的頭部或尾部,則空間管理會重新初始化該空閑列表。
          ??????? 可能會存在該放入空閑列表但有沒有放入的數(shù)據(jù)塊,運(yùn)行REBUILD_FREELISTS解決這個(gè)問題。
          ??? * 索引和表不同步了。需要執(zhí)行DUMP_ORPHAN_KEYS獲得信息,然后用ALTER INDEX ... REBUILD ONLINE同步
          ?
          ??? 4、如果修復(fù)中丟失了數(shù)據(jù),這些數(shù)據(jù)還能被檢索碼?
          ?
          ??? 當(dāng)數(shù)據(jù)庫被標(biāo)記為損壞時(shí),仍可以從索引中檢索數(shù)據(jù)。DUMP_ORPHAN_KEYS過程可以有助于檢索該信息。當(dāng)然這種方法檢索數(shù)據(jù)取決于索引和表之間數(shù)據(jù)冗余的數(shù)量。
          ?
          ?
          ?
          三、使對象可用
          ?
          ??? 1、損壞修復(fù)(使用FIX_CORRUPT_BLOCKS和SKIP_CORRUPT_BLOCKS)
          ?
          ??? 通過建立一個(gè)環(huán)境,跳過DBMS_REPAIR修復(fù)能力范圍之外的損壞,使損壞對象可用。如果該損壞包括了數(shù)據(jù)丟失,如數(shù)據(jù)塊中的壞行,所有這樣的數(shù)據(jù)塊都被FIX_CORRUPT_BLOCKS過程標(biāo)記為損壞。然后運(yùn)行SKIP_CORRUPT_BLOCKS跳過對象中被標(biāo)記為損壞的數(shù)據(jù)塊。當(dāng)設(shè)置跳過后,表和索引掃描就跳過所有被標(biāo)記成損壞的數(shù)據(jù)塊,這適用于介質(zhì)和軟件損壞數(shù)據(jù)塊兩者。
          ?
          ??? 2、跳過損壞數(shù)據(jù)塊時(shí)的意義
          ?
          ??? 如果索引和表不同步了,那么當(dāng)一個(gè)查詢僅僅探查索引,而下一個(gè)查詢探查索引和表兩者時(shí),SET TRANSACTION READ ONLY事務(wù)就可能有矛盾。如果表數(shù)據(jù)塊被標(biāo)記成損壞,那么兩個(gè)查詢就會返回不同的結(jié)果,這就破壞了只讀事務(wù)的規(guī)則。
          ??? 處理這個(gè)問題的一個(gè)方法是在SET TRANSACTION READ ONLY事務(wù)中不跳過損壞數(shù)據(jù)塊。當(dāng)選取被鏈接在一起的行時(shí)也會發(fā)生相同的問題,本質(zhì)上說,對相同行的查詢既可以又不可以訪問損壞數(shù)據(jù)塊,因此產(chǎn)生不同結(jié)果
          ?
          ?
          ?
          四、修復(fù)損壞和重建丟失的數(shù)據(jù)
          ?
          ??? 1、用DUMP_ORPHAN_KEYS過程恢復(fù)數(shù)據(jù)
          ?
          ??? DUMP_ORPHAN_KEYS過程報(bào)告指向損壞數(shù)據(jù)塊中的行的索引項(xiàng)。所有這些索引項(xiàng)都被插入到一個(gè)孤立鍵表中,該表存儲了損壞數(shù)據(jù)塊的鍵和行標(biāo)識。索引出了索引項(xiàng)信息之后,就可以使用ALTER INDEX ... REBUILD ONLINE語句重建該索引。
          ?
          ??? 2、用REBUILD_FREELISTS過程修復(fù)空閑列表
          ?
          ??? 如果是空閑列表(SEGMENT SPACE MANAGEMENT MANUAL)來管理段中的空閑空間時(shí),就使用該過程。
          ?
          ??? 當(dāng)在空閑列表的頭部或尾部找到了被標(biāo)記為“損壞”的數(shù)據(jù)塊時(shí),將重新初始化空閑列表,并返回一個(gè)錯(cuò)誤。這樣雖然從空閑列表中清除了錯(cuò)誤數(shù)據(jù)塊,但是它使得空閑列表不能訪問緊跟損壞數(shù)據(jù)塊之后的所有數(shù)據(jù)塊,此時(shí)可以使用REBUILD_FREELISTS過程來重新初始化空閑列表。 此時(shí)對象會被掃描,若適合作為空閑列表上的數(shù)據(jù)塊,則增加到這里面。
          ?
          ??? 3、用SEGMENT_FIX_STATUS過程修復(fù)段位圖
          ?
          ??? 對于用位圖(SEGMENT SPACE MANAGEMENT AUTO)來管理段中的空閑空間時(shí),使用這個(gè)過程。這個(gè)過程或者基于對應(yīng)的數(shù)據(jù)塊的當(dāng)前內(nèi)容重新計(jì)算位圖的狀態(tài),或者指定將位圖項(xiàng)設(shè)置成特殊的值。通常,狀態(tài)被正確得中心計(jì)算而不需要強(qiáng)行設(shè)置。
          ?
          ?
          ?
          五、示例
          ?
          ---------------------------------------------
          -- 首先用ADMIN_TABLES建立修復(fù)表/孤立鍵表
          -- 修復(fù)表用于表示錯(cuò)誤數(shù)據(jù)塊以及修復(fù)方法
          -- 修復(fù)表 -> FIX_CORRUPT_BLOCKS
          -- 孤立鍵表 -> DUMP_ORPHAN_KEYS
          ---------------------------------------------
          ?
          --先來建立修復(fù)表
          begin
          ? dbms_repair.admin_tables(table_name => 'REPAIR_WXQ',
          ?????????????????????????? table_type => dbms_repair.repair_table,
          ?????????????????????????? action???? => dbms_repair.create_action,
          ?????????????????????????? tablespace => 'WXQ_TBS2');
          end;
          /
          ?
          --查看一下
          SQL> desc REPAIR_WXQ
          Name??????????????? Type?????????? Nullable Default Comments
          ------------------- -------------- -------- ------- --------
          OBJECT_ID?????????? NUMBER??????????????????????????????????
          TABLESPACE_ID?????? NUMBER??????????????????????????????????
          RELATIVE_FILE_ID??? NUMBER??????????????????????????????????
          BLOCK_ID??????????? NUMBER??????????????????????????????????
          CORRUPT_TYPE??????? NUMBER??????????????????????????????????
          SCHEMA_NAME???????? VARCHAR2(30)????????????????????????????
          OBJECT_NAME???????? VARCHAR2(30)????????????????????????????
          BASEOBJECT_NAME???? VARCHAR2(30)?? Y????????????????????????
          PARTITION_NAME????? VARCHAR2(30)?? Y????????????????????????
          CORRUPT_DESCRIPTION VARCHAR2(2000) Y????????????????????????
          REPAIR_DESCRIPTION? VARCHAR2(200)? Y????????????????????????
          MARKED_CORRUPT????? VARCHAR2(10)????????????????????????????
          CHECK_TIMESTAMP???? DATE????????????????????????????????????
          FIX_TIMESTAMP?????? DATE?????????? Y????????????????????????
          REFORMAT_TIMESTAMP? DATE?????????? Y????????????????????????
          ?
          -- 用同樣的過程創(chuàng)建孤立鍵表
          begin
          ? dbms_repair.admin_tables(table_name => 'ORPHAN_WXQ',
          ?????????????????????????? table_type => dbms_repair.orphan_table,
          ?????????????????????????? action???? => dbms_repair.create_action,
          ?????????????????????????? tablespace => 'WXQ_TBS2');
          end;
          /
          ?
          --同樣來查看一下表結(jié)構(gòu)
          SQL> desc ORPHAN_WXQ
          Name?????????? Type???????? Nullable Default Comments
          -------------- ------------ -------- ------- --------
          SCHEMA_NAME??? VARCHAR2(30)??????????????????????????
          INDEX_NAME???? VARCHAR2(30)??????????????????????????
          IPART_NAME???? VARCHAR2(30) Y????????????????????????
          INDEX_ID?????? NUMBER????????????????????????????????
          TABLE_NAME???? VARCHAR2(30)??????????????????????????
          PART_NAME????? VARCHAR2(30) Y????????????????????????
          TABLE_ID?????? NUMBER????????????????????????????????
          KEYROWID?????? UROWID(4000)??????????????????????????
          KEY??????????? UROWID(4000)??????????????????????????
          DUMP_TIMESTAMP DATE??????????????????????????????????
          ?
          ?
          ?

          ---------------------------------------------
          -- 接著用CHECK_OBJECT來檢查損壞數(shù)量
          -- 注意:最終輸出為一個(gè)int型數(shù)字
          ---------------------------------------------
          declare
          ? num_corrupt int := 0;
          begin
          ? dbms_repair.check_object(schema_name?????? => 'WANGXIAOQI',
          ?????????????????????????? object_name?????? => 'T1',
          ?????????????????????????? repair_table_name => 'REPAIR_WXQ',
          ?????????????????????????? corrupt_count???? => num_corrupt);
          ? dbms_output.put_line('number corrupt: ' || to_char(num_corrupt));
          end;
          /
          ?
          -- 查看修復(fù)表
          select a.object_name,
          ?????? a.block_id,
          ?????? a.corrupt_type,
          ?????? a.marked_corrupt,
          ?????? a.corrupt_description,
          ?????? a.repair_description
          ? from repair_wxq a;
          ?
          OBJECT_NAME BLOCK_ID CORRUPT_TYPE MARKED_COR CORRUPT_DESCRIPTION REPAIR_DESCRIPTION
          ----------- -------- ------------ ---------- ------------------- ------------------
          ???????? T1??????? 3??????????? 1????? FALSE??????????????? ....?????????????? ....
          ?

          ---------------------------------------------
          -- 使用FIX_CORRUPT_BLOCKS來修理損壞數(shù)據(jù)塊
          --
          ---------------------------------------------
          declare
          ? num_fix int := 0;
          begin
          ? dbms_repair.fix_corrupt_blocks(schema_name?????? => 'WANGXIAOQI',
          ???????????????????????????????? object_name?????? => 'T1',
          ???????????????????????????????? object_type?????? => dbms_repair.table_object,
          ???????????????????????????????? repair_table_name => 'REPAIR_WXQ',
          ???????????????????????????????? fix_count???? => num_fix);
          ? dbms_output.put_line('num fix: ' || to_char(num_fix));
          end;
          /
          ?
          --確認(rèn)已做修復(fù)
          select a.object_name, a.block_id, a.marked_corrupt
          ? from repair_wxq a;
          ?
          OBJECT_NAME BLOCK_ID MARKED_COR
          ----------- -------- ----------
          ???????? T1??????? 3????? FALSE
          ?

          ----------------------------------------------------
          -- 使用DUMP_ORPHAN_KEYS來查找指向損壞數(shù)據(jù)塊的指引項(xiàng)
          --
          ----------------------------------------------------
          declare
          ? num_orphans int := 0;
          begin
          ? dbms_repair.dump_orphan_keys(schema_name?????? => 'WANGXIAOQI',
          ?????????????????????????????? object_name?????? => 'T1_PK',
          ?????????????????????????????? object_type?????? => dbms_repair.index_object,
          ?????????????????????????????? repair_table_name => 'REPAIR_WXQ',
          ?????????????????????????????? orphan_table_name => 'ORPHAN_WXQ',
          ?????????????????????????????? key_count???????? => num_orphans);
          ? dbms_output.put_line('orphan key count: ' || to_char(num_orphans));
          end;
          /
          ?

          ---------------------------------------------
          -- 使用REBUILD_FREELISTS重建空閑列表
          --
          ---------------------------------------------
          begin
          ? dbms_repair.rebuild_freelists(schema_name => 'WANGXIAOQI',
          ??????????????????????????????? object_name => 'T1',
          ??????????????????????????????? object_type => dbms_repair.table_object);
          end;
          /
          ?

          ---------------------------------------------
          -- 使用SKIP_CORRUPT_BLOCKS控制是否跳過壞塊
          --
          ---------------------------------------------
          begin
          ? dbms_repair.skip_corrupt_blocks(schema_name => 'WANGXIAOQI',
          ????????????????????????????????? object_name => 'T1',
          ????????????????????????????????? object_type => dbms_repair.table_object,
          ????????????????????????????????? flags?????? => dbms_repair.SKIP_FLAG);
          end;
          /
          ?
          --查看該表狀態(tài)
          select owner, table_name, skip_corrupt
          ? from dba_tables
          where table_name = 'T1';
          ?
          ?
          ?
          ?
          ?
          posted on 2009-07-31 21:03 decode360 閱讀(383) 評論(0)  編輯  收藏 所屬分類: 08.DBA
          主站蜘蛛池模板: 紫云| 贵定县| 磴口县| 曲阜市| 禹城市| 潢川县| 西乌珠穆沁旗| 长春市| 陆川县| 马边| 平阴县| 鹿邑县| 濮阳县| 平邑县| 成武县| 新泰市| 通州市| 滨海县| 马鞍山市| 金山区| 寿阳县| 安多县| 黄冈市| 涟水县| 克拉玛依市| 商水县| 汝州市| 丹东市| 施秉县| 宁安市| 克拉玛依市| 尉犁县| 弥渡县| 五大连池市| 普兰店市| 始兴县| 阿瓦提县| 重庆市| 金山区| 玉山县| 临桂县|