gdufo

           

          數(shù)據(jù)文件出現(xiàn)壞快的解決之一(如何利用dbms_repair來標記和跳過壞塊)

          http://blog.chinaunix.net/u1/50863/showart_400574.html

           

          第一步:準備試驗環(huán)境(建表空間,用戶,表,初始化一些數(shù)據(jù),然后破壞對應的數(shù)據(jù)文件)

          E:\Oracle\ora92\bin>sqlplus "/ as sysdba"

          SQL*Plus: Release 9.2.0.4.0 - Production on 星期一 3月 8 20:27:15 2004

          Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.


          連接到:
          Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
          With the Partitioning, OLAP and Oracle Data Mining options
          JServer Release 9.2.0.4.0 - Production

          SQL> select name from v$datafile;

          NAME
          --------------------------------------------------------------------------------
          E:\ORACLE\ORADATA\oracle92\SYSTEM01.DBF
          E:\ORACLE\ORADATA\oracle92\UNDOTBS01.DBF
          E:\ORACLE\ORADATA\oracle92\app01.DBF

          grant dba to test1107;

          SQL> create tablespace block datafile 'd:\oracle\oradata\block.dbf' size 2M;
          表空間已創(chuàng)建。
          SQL> create user test1107 identified by aaaa default tablespace block;
          用戶已創(chuàng)建
          SQL> conn test1107/aaaa;
          已連接。
          SQL> create table test tablespace block as select * from all_tables;
          表已創(chuàng)建。
          SQL> insert into test select * from test;
          已創(chuàng)建8行。
          SQL> /
          已創(chuàng)建16行。
          SQL> /
          已創(chuàng)建32行。
          SQL> /
          已創(chuàng)建64行。
          SQL> /
          已創(chuàng)建128行。
          SQL> /
          已創(chuàng)建256行。
          SQL> /
          已創(chuàng)建512行。
          SQL> /
          已創(chuàng)建1024行。
          SQL> /
          已創(chuàng)建2048行。
          SQL> /
          已創(chuàng)建4096行。
          SQL> /
          insert into test select * from test
          *
          ERROR 位于第 1 行:
          ORA-01653: 表test1107.TEST無法通過8(在表空間BLOCK中)擴展

          SQL> create index i_test on test(table_name);

          Index created

          SQL> alter system checkpoint;

          System altered

          SQL> connect sys/sys as sysdba
          已連接。
          SQL> shutdown immediate
          數(shù)據(jù)庫已經(jīng)關(guān)閉。
          已經(jīng)卸載數(shù)據(jù)庫。
          ORACLE 例程已經(jīng)關(guān)閉。

          --使用UltraEdit編輯block.dbf,修改幾個字符

          SQL> startup
          ORACLE 例程已經(jīng)啟動。

          Total System Global Area   72424008 bytes
          Fixed Size                   453192 bytes
          Variable Size              46137344 bytes
          Database Buffers           25165824 bytes
          Redo Buffers                 667648 bytes
          數(shù)據(jù)庫裝載完畢。
          數(shù)據(jù)庫已經(jīng)打開。
          QL> select count(*) from test1107.test;

          select count(*) from test1107.test

          ORA-01578: ORACLE 數(shù)據(jù)塊損壞(文件號13,塊號9)
          ORA-01110: 數(shù)據(jù)文件 13: 'D:\ORACLE\ORADATA\BLOCK.DBF'

           

          第二步:利用dbv檢查數(shù)據(jù)文件

          dbv file='d:\oracle\ora92\block.dbf' blocksize=8192 logfile='d:\work\temp\dbv.log'
            日志:
             DBVERIFY - 驗證完成

             檢查的頁總數(shù)         :256
             處理的頁總數(shù)(數(shù)據(jù)):112
             失敗的頁總數(shù)(數(shù)據(jù)):0
             處理的頁總數(shù)(索引):17
             失敗的頁總數(shù)(索引):0
             處理的頁總數(shù)(其它):10
             處理的總頁數(shù) (段)  : 0
             失敗的總頁數(shù) (段)  : 0
             空的頁總數(shù)            :102
             標記為損壞的總頁數(shù):15
             匯入的頁總數(shù)           :0


          第三步:利用dbms_repair包進行處理
          1.創(chuàng)建管理表:
          SQL> connect sys/sys as sysdba
          Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0
          Connected as SYS

          SQL> exec DBMS_REPAIR.ADMIN_TABLES('REPAIR_TABLE',1,1,'USERS');

          PL/SQL procedure successfully completed

          SQL> exec DBMS_REPAIR.ADMIN_TABLES('ORPHAN_TABLE',2,1,'USERS');

          PL/SQL procedure successfully completed

          2.檢查壞塊:

           declare
              cc number;
           begin
              dbms_repair.check_object(schema_name => 'TEST1107',object_name => 'TEST',corrupt_count => cc);
              dbms_output.put_line(a => to_char(cc));
           end;

           15

          PL/SQL 過程已成功完成。     

          看到這里用dbms_repair.check,檢查的結(jié)果corrupt_count=15,有15個塊損壞,和dbv的結(jié)果一致。

          check完之后,在我們剛在創(chuàng)建的REPAIR_TABLE中查看塊損壞信息:   

          SQL> SELECT * from repair_table
          在這個table中,可以看到損壞的block的信息,這里的信息和我們用dbv得到的一致。
          我這個實驗是在9i下模擬的,注意看MARKED_CORRUPT的值,這里經(jīng)過check_object后,已經(jīng)標識為TRUE了。
          所以可以直接進行第四步了。按照oracle文檔上的說法,在8i下,check_object只會檢查壞塊,MARKED_CORRUPT為false需要使用第3步,fix_corrupt_blocks定位 ,修改MARKED_CORRUPT為true,同時更新CHECK_TIMESTAMP。
          這里我們經(jīng)過實驗,確認在9i下跳過第3步,是完全可行的。那么8i是否需要執(zhí)行第三步,我沒有實驗過,但推測應該是不可以跳過的。  

          3.定位壞塊:

          dbms_repair.fix_corrupt_blocks     

          只有將壞塊信息寫入定義的REPAIR_TABLE后,才能定位壞塊。 
          declare
            cc number;
          begin
            dbms_repair.fix_corrupt_blocks(schema_name => 'TEST1107',object_name => 'TEST',fix_count => cc);
            dbms_output.put_line(a => to_char(cc));
          end;

          4.跳過壞塊:

          我們前面雖然定位了壞塊,但是,如果我們訪問table還是會得到錯誤信息。   
          這里需要用skip_corrupt_blocks來跳過壞塊:

          SQL> exec dbms_repair.skip_corrupt_blocks(schema_name => 'TEST1107',object_name => 'TEST',flags => 1);

          PL/SQL procedure successfully completed

          SQL> select count(*) from test1107.test;

            COUNT(*)
          ----------
                4490

           

          5.處理index上的無效鍵值;

          SQL> declare
            2  cc number;
            3  begin
            4  dbms_repair.dump_orphan_keys(schema_name => 'TEST1107',object_name => 'I_TEST',object_type => 2,
            5  repair_table_name => 'REPAIR_TABLE',orphan_table_name => 'ORPHAN_TABLE',key_count => CC);
            6  end;
            7  /

          PL/SQL procedure successfully completed

          SQL> SELECT * FROM ORPHAN_TABLE;

          22 rows selected

          表示損失了22行數(shù)據(jù)

          我們根據(jù)這個結(jié)果來考慮是否需要rebuild index.

           

          6.重建freelist:rebuild_freelists

          SQL> exec dbms_repair.rebuild_freelists(schema_name => 'TEST1107',object_name => 'TEST');

          PL/SQL procedure successfully completed

          posted on 2009-11-25 22:28 gdufo 閱讀(1983) 評論(0)  編輯  收藏 所屬分類: Database (oracle, sqlser,MYSQL)

          導航

          統(tǒng)計

          常用鏈接

          留言簿(6)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          Hibernate

          友情鏈接

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 大方县| 柏乡县| 寿阳县| 镶黄旗| 明水县| 时尚| 山阴县| 宜兴市| 广德县| 稻城县| 禄丰县| 河池市| 阳信县| 抚州市| 新巴尔虎右旗| 长顺县| 阳谷县| 安新县| 乌鲁木齐县| 大余县| 巨鹿县| 崇阳县| 恭城| 遂平县| 罗甸县| 安徽省| 营山县| 淳安县| 潞西市| 锡林浩特市| 文山县| 行唐县| 亳州市| 罗田县| 温宿县| 清徐县| 化德县| 扎兰屯市| 安远县| 台州市| 海安县|