使用dbms_repair修复块损坏的例子

dbms_repair是从oracle8i开始提供的

我们可以用设置event的方法来处理坏块:

http://www.itpub.net/showthread.php?threadid=201766&pagenumber=

但是当数据量很大,或7*24的系统时,这样的方法就不是很合适了。这里我们使用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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值