使用dbms_repair修复块损坏的具体示例
|
使用dbms_repair修复块损坏的具体示例: SQL> create tablespace block datafile "D:oracleoradataoracle9ilock.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:ORACLEORADATAORACLE9IBLOCK.DBF" 用dbv检查: C:Documents and Settingsduanl>dbv file="D:oracleoradataoracle9ilock.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:oracleoradataoracle9ilock.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:ORACLEORADATAORACLE9IBLOCK.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 |
