壞塊標記並skip

Xinspirit發表於2012-08-30

1.       首先建立測試用的表空間

SQL> create tablespace test

  2  datafile 'D:\10g\product\10.2.0\oradata\orcl\test.dbf' size 1M;

 

表空間已建立。

2.       建立測試用使用者

SQL>  create user test identified by test

  2   default tablespace test;

 

使用者已建立。

3.       授予許可權

    SQL> grant connect,resource,create table,exp_full_database to test

 

授權成功。

4.       設定限額

SQL> alter user test quota unlimited on test;

 

使用者已更改。

5.       切換使用者建立測試用表,並插入語句

SQL> create table test

  2  (i int,

  3   a number);

 

表已建立。

 

SQL> insert into test values (2,3);

 

已建立 1 行。

SQL> insert into test select * from test;

 

已建立 1 行。

 

SQL> /

 

已建立2行。

 

SQL> /

 

已建立4行。

 

SQL> /

 

已建立8行。

 

SQL> /

 

已建立16行。

 

SQL> /

 

已建立32行。

 

SQL> /

 

已建立64行。

 

SQL> /

 

已建立128行。

 

SQL> /

 

已建立256行。

 

SQL> /

 

已建立512行。

 

SQL> /

 

已建立1024行。

 

SQL> /

 

已建立2048行。

 

SQL> /

 

已建立4096行。

 

SQL> /

 

已建立8192行。

 

SQL> /

 

已建立16384行。

 

SQL> /

 

已建立32768行。

 

SQL> /

insert into test select * from test

*

1 行出現錯誤:

ORA-01653: TEST.TEST 無法透過 8 (在表空間 TEST ) 擴充套件

塞滿為止

6.       先做一個查詢

SQL> select count(*) from test;

 

  COUNT(*)

----------

     65536

7.       關庫,冷備份資料檔案

SQL> shutdown immediate

資料庫已經關閉。

已經解除安裝資料庫。

ORACLE 例程已經關閉。

8.       使用UE編輯器對資料檔案進行編譯,隨便修改幾個資料,造成壞塊即可

9.       OK,成功出現壞塊

SQL> select count(*) from test;

select count(*) from test

                     *

1 行出現錯誤:

ORA-01578: ORACLE 資料塊損壞 (檔案號 5, 塊號 79)

ORA-01110: 資料檔案 5: 'D:\10G\PRODUCT\10.2.0\ORADATA\ORCL\TEST.DBF'

告警日誌顯示:

Reread of rdba: 0x0140004f (file 5, block 79) found same corrupted data

Thu Aug 30 10:03:44 2012

Corrupt Block Found

         TSN = 7, TSNAME = TEST

         RFN = 5, BLK = 79, RDBA = 20971599

         BJN = 52706, BJD = 52706, BJECT = TEST, SUBOBJECT =

         SEGMENT WNER = TEST, SEGMENT TYPE = Table Segment

當然此時如果使用exp進行資料匯出也是會出現錯誤

即將匯出 TEST 的物件...

. 正在匯出資料庫連結

. 正在匯出序號

. 正在匯出簇定義

. 即將匯出 TEST 的表透過常規路徑...

. . 正在匯出表                            TEST

EXP-00056: 遇到 ORACLE 錯誤 1578

ORA-01578: ORACLE 資料塊損壞 (檔案號 5, 塊號 79)

ORA-01110: 資料檔案 5: 'D:\10G\PRODUCT\10.2.0\ORADATA\ORCL\TEST.DBF'

10.   因為OBJD52706,我們可以進一步確定壞塊型別,如果是索引壞塊則刪除重建即可,表壞塊則需要進行修復

SQL> select owner,object_name,object_type from dba_objects where object_id=52706

;

 

 

 

OWNER

------------------------------

OBJECT_NAME

--------------------------------------------------

OBJECT_TYPE

-------------------

TEST

TEST

TABLE

11.   使用DBV工具分析

C:\Documents and Settings\Administrator>dbv file='D:\10G\PRODUCT\10.2.0\ORADATA

12.       ORCL\TEST.DBF'

13.        

14.       DBVERIFY: Release 10.2.0.1.0 - Production on 星期四 8 30 10:04:44 2012

15.        

16.       Copyright (c) 1982, 2005, Oracle.  All rights reserved.

17.        

18.       DBVERIFY - 開始驗證: FILE = D:\10G\PRODUCT\10.2.0\ORADATA\ORCL\TEST.DBF

19.       79 標記為損壞

20.       Corrupt block relative dba: 0x0140004f (file 5, block 79)

21.       Bad check value found during dbv:

22.       Data in bad block:

23.        type: 6 format: 2 rdba: 0x0140004f

24.        last change scn: 0x0000.003848a4 seq: 0x1 flg: 0x06

25.        spare1: 0x0 spare2: 0x0 spare3: 0x0

26.        consistency value in tail: 0x48a40601

27.        check value in block header: 0xa4cc

28.        computed block checksum: 0x509

29.        

30.        

31.        

32.       DBVERIFY - 驗證完成

33.        

34.       檢查的頁總數: 128

35.       處理的頁總數 (資料): 109

36.       失敗的頁總數 (資料): 0

37.       處理的頁總數 (索引): 0

38.       失敗的頁總數 (索引): 0

39.       處理的頁總數 (其它): 18

40.       處理的總頁數 ()  : 0

41.       失敗的總頁數 ()  : 0

42.       空的頁總數: 0

43.       標記為損壞的總頁數: 1

44.       流入的頁總數: 0

45.           最高塊 SCN : 3688974 (0.3688974)資料檔案

46.   使用dbms_repair包進行壞塊標記

建立REPAIR_CORRUPT_TAB

SQL> exec dbms_repair.admin_tables(-

> table_name=>'REPAIR_CORRUPT_TAB',-

> table_type=>dbms_repair.repair_table,-

> action=>dbms_repair.create_action);

 

PL/SQL 過程已成功完成。

檢測壞塊,資訊存入表中

declare num_corrupt int;

 begin

 num_corrupt:=0;

 dbms_repair.check_object(

 schema_name=>'TEST',

 object_name=>'TEST',

 repair_table_name=>'REPAIR_CORRUPT_TAB',

 corrupt_count=>num_corrupt);

 dbms_output.put_line(num_corrupt);

 end;

 /

PL/SQL 過程已成功完成。

SQL> select schema_name,object_name,relative_file_id,block_id,repair_description

 from repair_corrupt_tab;

上面的sql語句可以顯示壞塊的資訊,由於太長就別一一貼出來了。

標記壞塊

declare num_fix int;

begin

num_fix:=0;

dbms_repair.fix_corrupt_blocks(

schema_name=>'TEST',

object_name=>'TEST',

object_type=>DBMS_REPAIR.TABLE_OBJECT,

repair_table_name=>'REPAIR_CORRUPT_TAB',

fix_count=>num_fix);

end;

/

PL/SQL 過程已成功完成

給壞塊打完標籤之後,我們sikp這些壞塊

SQL> exec dbms_repair.skip_corrupt_blocks('TEST','TEST');

 

PL/SQL 過程已成功完成。

47 再來查詢下看看

     SQL> show user;

USER "SYS"

SQL> conn test/test

已連線。

SQL> select count(*) from test;

 

 

 

    COUNT(*)

----------

     64876

 65536-64876=660 損失了660條資料

再來看下exp

即將匯出 TEST 的表透過常規路徑...

 . 正在匯出表                            TEST匯出了       64876

 正在匯出同義詞

 正在匯出檢視

 正在匯出儲存過程

 正在匯出運算子

 正在匯出引用完整性約束條件

 正在匯出觸發器

 正在匯出索引型別

 正在匯出點陣圖, 功能性索引和可擴充套件索引

 正在匯出後期表活動

 正在匯出實體化檢視

 正在匯出快照日誌

 正在匯出作業佇列

 正在匯出重新整理組和子組

 正在匯出維

 正在匯出 post-schema 過程物件和操作

 正在匯出統計資訊

成功終止匯出, 沒有出現警告。

已經可以成功匯出

總結:此種方法可以在有資料壞塊的情況下進行標記壞塊跳過壞塊匯出資料,但是會一定程度上丟失資料。具體採用何種方法還要看業務的需求和資料的重要性。

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

相關文章