程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> 其他數據庫知識 >> 更多數據庫知識 >> 實例:dbms_repair修復塊損壞

實例:dbms_repair修復塊損壞

編輯:更多數據庫知識

SQL> create tablespace block datafile 'D:\oracle\oradata\oracle9i\block.dbf' size 5M;

Tablespace created

SQL> connect dlinger/dlinger

Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0

Connected as dlinger

QL> create table test tablespace block as select * from all_tables;

Table created

SQL> insert into test select * from test;

806 rows inserted

SQL> insert into test select * from test;

1612 rows inserted

SQL> insert into test select * from test;

3224 rows inserted

SQL> insert into test select * from test;

6448 rows inserted

SQL> insert into test select * from test;

insert into test select * from test

ORA-01653: 表DLINGER.TEST無法通過128(在表空間BLOCK中)擴展

SQL> commit;

Commit complete

SQL> select count(*) from test;

COUNT(*)

----------

12896

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

數據庫已經關閉。

已經卸載數據庫。

ORACLE 例程已經關閉。

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

SQL> startup

ORACLE 例程已經啟動。

Total System Global Area 72424008 bytes

Fixed Size 453192 bytes

Variable Size 46137344 bytes

Database Buffers 25165824 bytes

Redo Buffers 667648 bytes

數據庫裝載完畢。

數據庫已經打開。

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

select count(*) from dlinger.test

*

ERROR 位於第 1 行:

ORA-01578: ORACLE 數據塊損壞(文件號14,塊號160)

ORA-01110: 數據文件 14: 'D:\ORACLE\ORADATA\ORACLE9I\BLOCK.DBF'

用dbv檢查:

C:\Documents and Settings\duanl>dbv file='D:\oracle\oradata\oracle9i\block.dbf'

blocksize=8192

DBVERIFY: Release 9.2.0.1.0 - Production on 星期二 8月 24 19:58:15 2004

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

DBVERIFY - 驗證正在開始 : FILE = D:\oracle\oradata\oracle9i\block.dbf

標記為損壞的頁160

***

Corrupt block relative dba: 0x038000a0 (file 14, block 160)

Bad check value found during dbv:

Data in bad block -

type: 6 format: 2 rdba: 0x038000a0

last change scn: 0x0000.0035f5c2 seq: 0x1 flg: 0x06

consistency value in tail: 0xf5c20601

check value in block header: 0x3681, computed block checksum: 0x5bb

spare1: 0x0, spare2: 0x0, spare3: 0x0

***

DBVERIFY - 驗證完成

檢查的頁總數 :640

處理的頁總數(數據):510

失敗的頁總數(數據):0

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

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

處理的頁總數(其它):9

處理的總頁數 (段) : 0

失敗的總頁數 (段) : 0

空的頁總數 :120

標記為損壞的總頁數:1

匯入的頁總數 :0

使用dbms_repair包

1.創建管理表:

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.檢查壞塊:dbms_repair.check_object

SQL> declare

2 cc number;

3 begin

4 dbms_repair.check_object(schema_name => 'DLINGER',object_name => 'TEST',cor

rupt_count => cc);

5 dbms_output.put_line(a => to_char(cc));

6 end;

7 /

1

PL/SQL 過程已成功完成。

看到這裡用dbms_repair.check,檢查的結果corrupt_count=1,有一個塊損壞,和dbv的結果一致。

check完之後,在我們剛在創建的REPAIR_TABLE中查看塊損壞信息:

SQL> SELECT object_name, relative_file_id, block_id,marked_corrupt, corrupt_description, repair_description,

2 CHECK_TIMESTAMP from repair_table;

OBJECT_NAME RELATIVE_FILE_ID BLOCK_ID MARKED_CORRUPT CORRUPT_DESCRIPTION REPAIR_DESCRIPTION CHECK_TIMESTAMP

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

TEST 14 160 TRUE mark block software corrupt 2004-8-24 21:46

在這個table中,可以看到損壞的block的信息,這裡的信息和我們用dbv得到的一致。

我們這個實驗是在9i下模擬的,我們注意看MARKED_CORRUPT的值,這裡經過check_object後,已經標識為TRUE了。

所以可以直接進行第四步了。

按照oracle文檔上的說法,在8i下,check_object只會檢查壞塊,MARKED_CORRUPT為false

需要使用第3步,fix_corrupt_blocks定位 ,修改MARKED_CORRUPT為true,同時更新CHECK_TIMESTAMP。

這裡我們經過實驗,確認在9i下跳過第3步,是完全可行的。

那麼8i是否需要執行第三步,我沒有實驗過,但推測應該是不可以跳過的。

3.定位壞塊:dbms_repair.fix_corrupt_blocks

只有將壞塊信息寫入定義的REPAIR_TABLE後,才能定位壞塊。

declare

cc number;

begin

dbms_repair.fix_corrupt_blocks(schema_name => 'DLINGER',object_name => 'TEST',fix_count => cc);

dbms_output.put_line(a => to_char(cc));

end;

4.跳過壞塊:

我們前面雖然定位了壞塊,但是,如果我們訪問table:

SQL> select count(*) from dlinger.dbblock;

select count(*) from dlinger.dbblock

ORA-01578: ORACLE 數據塊損壞(文件號14,塊號154)

ORA-01110: 數據文件 14: 'D:\ORACLE\ORADATA\ORACLE9I\BLOCK.DBF'

還是會得到錯誤信息。

這裡需要用skip_corrupt_blocks來跳過壞塊:

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

PL/SQL procedure successfully completed

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

COUNT(*)

----------

12850

丟失了12896-12850=46行數據。

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

declare

cc number;

begin

dbms_repair.dump_orphan_keys(schema_name => 'DLINGER',object_name => 'I_TEST',object_type => 2,

repair_table_name => 'REPAIR_TABLE',orphan_table_name => 'ORPHAN_TABLE',key_count => CC);

end;

/

SQL> SELECT * FROM ORPHAN_TABLE;

SCHEMA_NAME INDEX_NAME IPART_NAME INDEX_ID TABLE_NAME PART_NAME TABLE_ID KEYROWID KEY DUMP_TIMESTAMP

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

DLINGER I_TEST 30258 TEST 30257 AAAHYxAOwAAAIADA0A *BAAAAAAMTE9HTU5SQ19HU0lJ/g 2004-8-25 22:1

DLINGER I_TEST 30258 TEST 30257 AAAHYxAOwAAAIADAsA *BAAAAAAMTE9HTU5SQ19HVExP/g 2004-8-25 22:1

..............................................

DLINGER I_TEST 30258 TEST 30257 AAAHYxAOwAAAIADB0A *BAAAAAAPTE9HTU5SX0xPQkZSQUck/g 2004-8-25 22:1

DLINGER I_TEST 30258 TEST 30257 AAAHYxAOwAAAIADBYA *BAAAAAAMTE9HTU5SX1RZUEUk/g 2004-8-25 22:1

DLINGER I_TEST 30258 TEST 30257 AAAHYxAOwAAAIADAQA *BAAAAAALTE9HTU5SX1VJRCT+ 2004-8-25 22:1

DLINGER I_TEST 30258 TEST 30257 AAAHYxAOwAAAIADAoA *BAAAAAAMTE9HTU5SX1VTRVIk/g 2004-8-25 22:1

46 rows selected

和上面我們看到的損失的數據行數吻合。

我們根據這個結果來考慮是否需要rebuild index.

6.重建freelist:rebuild_freelists

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

PL/SQL procedure successfully completed

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved