使用dbms_repair修复坏块

使用dbms_repair修复坏块

SQL> create tablespace block datafile 'c:/backup/block.dbf' size 1m;

表空间已创建。

SQL> grant dba to hwj identified by hwj;

授权成功。

SQL> conn hwj/hwj
已连接。
SQL> create table test tablespace block as select * from scott

表已创建。

SQL> insert into test select * from test;

已创建14行。

SQL> /

已创建28行。

SQL> /

已创建56行。

SQL> /

已创建112行。

SQL> /

已创建224行。

SQL> /

已创建448行。

SQL> /

已创建896行。

SQL> /

已创建1792行。

SQL> /

已创建3584行。

SQL> /

已创建7168行。

SQL> /
insert into test select * from test
*
第 1 行出现错误:
ORA-01653: 表 HWJ.TEST 无法通过 8 (在表空间 BLOCK 中) 扩展

SQL> commit;

提交完成。

SQL> select count(*) from test;

  COUNT(*)                                                                     
----------                                                                     
     14336                                                                     

SQL> create index i_test on test(ename);

索引已创建。

SQL> alter system checkpoint;

系统已更改。

SQL> conn / as sysdba
已连接。
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。

--使用UltraEdit编辑block.dbf,修改几个字符

SQL> startup
ORACLE 例程已经启动。

Total System Global Area  289406976 bytes                                      
Fixed Size                  1248600 bytes                                      
Variable Size              88081064 bytes                                      
Database Buffers          197132288 bytes                                      
Redo Buffers                2945024 bytes                                      
数据库装载完毕。
数据库已经打开。


SQL> select count(*) from hwj.test;
select count(*) from hwj.test
                         *
第 1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 9, 块号 90)
ORA-01110: 数据文件 9: 'C:/BACKUP/BLOCK.DBF'

用dbv检查:
C:/>dbv file=C:/backup/BLOCK.DBF blocksize=8192

DBVERIFY: Release 10.2.0.1.0 - Production on 星期六 3月 21 21:44:25 2009

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

DBVERIFY - 开始验证: FILE = C:/backup/BLOCK.DBF
页 90 标记为损坏
Corrupt block relative dba: 0x0240005a (file 9, block 90)
Bad check value found during dbv:
Data in bad block:
 type: 6 format: 2 rdba: 0x0240005a
 last change scn: 0x0000.001611d5 seq: 0x1 flg: 0x06
 spare1: 0x0 spare2: 0x0 spare3: 0x0
 consistency value in tail: 0x11d50601
 check value in block header: 0xfbaa
 computed block checksum: 0xf0d6

 

DBVERIFY - 验证完成

检查的页总数: 128
处理的页总数 (数据): 109
失败的页总数 (数据): 0
处理的页总数 (索引): 0
失败的页总数 (索引): 0
处理的页总数 (其它): 18
处理的总页数 (段)  : 0
失败的总页数 (段)  : 0
空的页总数: 0
标记为损坏的总页数: 1
流入的页总数: 0
最高块 SCN            : 1446360 (0.1446360)

使用dbms_repair包

1.创建管理表:
SQL> conn / as sysdba
已连接。
SQL> exec DBMS_REPAIR.ADMIN_TABLES('REPAIR_TABLE',1,1,'USERS');
--表数据
PL/SQL 过程已成功完成。
--索引数据
SQL> exec DBMS_REPAIR.ADMIN_TABLES('ORPHAN_TABLE',2,1,'USERS');

PL/SQL 过程已成功完成。

2.检查坏块:dbms_repair.check_object
SQL> SET SERVEROUTPUT ON
SQL> declare
  2   cc number;
  3   begin
  4   dbms_repair.check_object(schema_name => 'HWJ',object_name => 'TEST',corrupt_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,CHECK_TIMESTAMP from repair_table;

OBJECT_NAME                    RELATIVE_FILE_ID   BLOCK_ID MARKED_COR          
------------------------------ ---------------- ---------- ----------          
CORRUPT_DESCRIPTION                                                            
--------------------------------------------------------------------------------
REPAIR_DESCRIPTION                                                             
--------------------------------------------------------------------------------
CHECK_TIMESTAM                                                                 
--------------                                                                 
TEST                                          9         90 TRUE                
                                                                               
mark block software corrupt                                                    
21-3月 -09                                                                     
                                                                               

OBJECT_NAME                    RELATIVE_FILE_ID   BLOCK_ID MARKED_COR          
------------------------------ ---------------- ---------- ----------          
CORRUPT_DESCRIPTION                                                            
--------------------------------------------------------------------------------
REPAIR_DESCRIPTION                                                             
--------------------------------------------------------------------------------
CHECK_TIMESTAM                                                                 
--------------                                                                 
TEST                                          9         90 TRUE                
                                                                               
mark block software corrupt                                                    
21-3月 -09  
在这个table中,可以看到损坏的block的信息,这里的信息和我们用dbv得到的一致。
我们注意看MARKED_CORRUPT的值,这里经过check_object后,已经标识为TRUE了。

3.跳过坏块:

我们前面虽然定位了坏块,但是,如果我们访问table: 
SQL> select count(*) from hwj.test;
select count(*) from hwj.test
                         *
第 1 行出现错误:
ORA-01578: ORACLE 数据块损坏 (文件号 9, 块号 90)
ORA-01110: 数据文件 9: 'C:/BACKUP/BLOCK.DBF'
还是会得到错误信息。

这里需要用skip_corrupt_blocks来跳过坏块:
SQL> exec dbms_repair.skip_corrupt_blocks(schema_name => 'HWJ',object_name => 'TEST',flags => 1);

PL/SQL 过程已成功完成。

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

  COUNT(*)                                                                     
----------                                                                     
     14166  
   
丢失了14336-14166=170行数据。

4.处理index上的无效键值;dump_orphan_keys
SQL> declare
  2   cc number;
  3   begin
  4   dbms_repair.dump_orphan_keys(schema_name => 'HWJ',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 过程已成功完成。

SQL> SELECT * FROM ORPHAN_TABLE;
.................

已选择170行。
和上面我们看到的损失的数据行数吻合。

我们根据这个结果来考虑是否需要rebuild index

你可能感兴趣的:(使用dbms_repair修复坏块)