數(shù)據(jù)文件出現(xiàn)壞快的解決之一(如何利用dbms_repair來(lái)標(biāo)記和跳過(guò)壞塊)
http://blog.chinaunix.net/u1/50863/showart_400574.html
第一步:準(zhǔn)備試驗(yàn)環(huán)境(建表空間,用戶,表,初始化一些數(shù)據(jù),然后破壞對(duì)應(yīng)的數(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無(wú)法通過(guò)8(在表空間BLOCK中)擴(kuò)展
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ù)庫(kù)已經(jīng)關(guān)閉。
已經(jīng)卸載數(shù)據(jù)庫(kù)。
ORACLE 例程已經(jīng)關(guān)閉。
--使用UltraEdit編輯block.dbf,修改幾個(gè)字符
SQL> startup
ORACLE 例程已經(jīng)啟動(dò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ù)庫(kù)裝載完畢。
數(shù)據(jù)庫(kù)已經(jīng)打開(kāi)。
QL> select count(*) from test1107.test;
select count(*) from test1107.test
ORA-01578: ORACLE 數(shù)據(jù)塊損壞(文件號(hào)13,塊號(hào)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 - 驗(yàn)證完成
檢查的頁(yè)總數(shù) :256
處理的頁(yè)總數(shù)(數(shù)據(jù)):112
失敗的頁(yè)總數(shù)(數(shù)據(jù)):0
處理的頁(yè)總數(shù)(索引):17
失敗的頁(yè)總數(shù)(索引):0
處理的頁(yè)總數(shù)(其它):10
處理的總頁(yè)數(shù) (段) : 0
失敗的總頁(yè)數(shù) (段) : 0
空的頁(yè)總數(shù) :102
標(biāo)記為損壞的總頁(yè)數(shù):15
匯入的頁(yè)總數(shù) :0
第三步:利用dbms_repair包進(jìn)行處理
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 過(guò)程已成功完成。
看到這里用dbms_repair.check,檢查的結(jié)果corrupt_count=15,有15個(gè)塊損壞,和dbv的結(jié)果一致。
check完之后,在我們剛在創(chuàng)建的REPAIR_TABLE中查看塊損壞信息:
SQL> SELECT * from repair_table
在這個(gè)table中,可以看到損壞的block的信息,這里的信息和我們用dbv得到的一致。
我這個(gè)實(shí)驗(yàn)是在9i下模擬的,注意看MARKED_CORRUPT的值,這里經(jīng)過(guò)check_object后,已經(jīng)標(biāo)識(shí)為TRUE了。
所以可以直接進(jìn)行第四步了。按照oracle文檔上的說(shuō)法,在8i下,check_object只會(huì)檢查壞塊,MARKED_CORRUPT為false需要使用第3步,fix_corrupt_blocks定位 ,修改MARKED_CORRUPT為true,同時(shí)更新CHECK_TIMESTAMP。
這里我們經(jīng)過(guò)實(shí)驗(yàn),確認(rèn)在9i下跳過(guò)第3步,是完全可行的。那么8i是否需要執(zhí)行第三步,我沒(méi)有實(shí)驗(yàn)過(guò),但推測(cè)應(yīng)該是不可以跳過(guò)的。
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.跳過(guò)壞塊:
我們前面雖然定位了壞塊,但是,如果我們?cè)L問(wèn)table還是會(huì)得到錯(cuò)誤信息。
這里需要用skip_corrupt_blocks來(lái)跳過(guò)壞塊:
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上的無(wú)效鍵值;
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ù)這個(gè)結(jié)果來(lái)考慮是否需要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 閱讀(1982) 評(píng)論(0) 編輯 收藏 所屬分類: Database (oracle, sqlser,MYSQL)