手工构造逻辑坏块一例

以前同事问我,能否构造一个逻辑坏块?我们知道坏块通常分为物理坏块和逻辑坏块两种。

物理坏块:通常是由于硬件损坏如磁盘异常导致;

逻辑坏块:通常是由于oracle bug导致,比如data block和index block数据不一致等;

那么如何构造一个逻辑坏块呢?我们这里就来构造一个index block内容跟其对应的data block
内容不一致的情况,其实非常简单,我们随便改下index entry就行。
SQL> show user

USER is "ROGER"

SQL> create table t1 as select * from dba_objects where rownum < 100;

Table created.

SQL> create index idx_id on t1(object_id);

Index created.

SQL> select dbms_rowid.rowid_relative_fno(rowid) file#,
  2         dbms_rowid.rowid_block_number(rowid) blk#
  3  from t1;

     FILE#       BLK#
---------- ----------
         6      28516
         6      28516
         6      28516
         6      28516
         .      .....
         .      .....
         .      .....
         .      .....
         .      .....
         .      .....
         6      28517
         6      28517
         6      28517
         6      28517
         6      28517
         6      28517

99 rows selected.

SQL> select object_id from dba_objects where object_name=upper('idx_id');

 OBJECT_ID
----------
     54609

SQL> ALTER SESSION SET EVENTS 'immediate trace name treedump level 54609';

Session altered.


++++++++++++++++++ trace file +++++++++++++++++++++++++++++

--- index treedump
*** 2012-03-05 08:59:56.763
*** ACTION NAME:() 2012-03-05 08:59:56.762
*** MODULE NAME:(SQL*Plus) 2012-03-05 08:59:56.762
*** SERVICE NAME:(SYS$USERS) 2012-03-05 08:59:56.762
*** SESSION ID:(159.5) 2012-03-05 08:59:56.762
----- begin tree dump
leaf: 0x1806f9c 25194396 (0: nrow: 99 rrow: 99)
----- end tree dump

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

SQL> select dbms_utility.data_block_address_file(TO_NUMBER('1806f9c', 'XXXXXXXX')) file_id,
  2         dbms_utility.data_block_address_block(TO_NUMBER('1806f9c', 'XXXXXXXX')) block_id
  3    from dual;

   FILE_ID   BLOCK_ID
---------- ----------
         6      28572
++++++ index block structure ++++++

BBED> set file 6 block 28572

        FILE#           6
        BLOCK#          28572

BBED> p kdxle

struct kdxle, 32 bytes                      @100
   struct kdxlexco, 16 bytes                @100
      ub1 kdxcolev                          @100      0x00
      ub1 kdxcolok                          @101      0x00
      ub1 kdxcoopc                          @102      0x80
      ub1 kdxconco                          @103      0x02
      ub4 kdxcosdc                          @104      0x00000000
      sb2 kdxconro                          @108      99
      b2 kdxcofbo                           @110      234
      b2 kdxcofeo                           @112      6844
      b2 kdxcoavs                           @114      6610
   b2 kdxlespl                              @116      0
   sb2 kdxlende                             @118      0
   ub4 kdxlenxt                             @120      0x00000000
   ub4 kdxleprv                             @124      0x00000000
   ub1 kdxledsz                             @128      0x00
   ub1 kdxleunuse                           @129      0x00


++++++  我们这里修改 kdxlexco 即可,我这里就修改kdxcofbo吧。++++++

BBED> set off 110

        OFFSET          110

BBED> modify /x e9

Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
 File: /home/ora10g/oradata/roger/roger02.dbf (6)
 Block: 28572            Offsets:  110 to  621           Dba:0x01806f9c
------------------------------------------------------------------------
 e900bc1a d2190000 00000000 00000000 00000000 0000601f 0000541f 481f3c1f
 301f241f 181f0c1f 001ff41e e81edc1e d01ec41e b81eac1e a01e941e 881e7c1e
 701e641e 581e4c1e 401e341e 281e1c1e 101e041e f81dec1d e01dd41d c81dbc1d
 b01da41d 981d8c1d 801d741d 681d5c1d 501d441d 381d2c1d 201d141d 081dfc1c
 f01ce41c d81ccc1c c01cb41c a81c9c1c 901c841c 781c6c1c 601c541c 481c3c1c
 301c241c 181c0c1c 001cf41b e81bdc1b d01bc41b b81bac1b a01b941b 881b7c1b
 701b641b 581b4c1b 401b341b 281b1c1b 101b041b f81aec1a e01ad41a c81abc1a
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

 <32 bytes per line>

BBED> sum apply

Check value for File 6, Block 28572:
current = 0x7798, required = 0x7798

++++++ check ++++++

SQL> conn /as sysdba

SQL> select * from V$DATABASE_BLOCK_CORRUPTION;

     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
         6      50403          1                  0 ALL ZERO
         6      28572          1            2779528 UNKNOWN
         6      51684          1            1527408 UNKNOWN


我们可以发现 block 28572 的CORRUPTION_CHANGE# 大于0. 说明该block为逻辑坏块。
++++++ rman check ++++++

RMAN> backup validate check logical database;

Starting backup at 05-MAR-12
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=141 devtype=DISK
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
input datafile fno=00005 name=/home/ora10g/oradata/roger/roger01.dbf
input datafile fno=00002 name=/home/ora10g/oradata/roger/undotbs01.dbf
input datafile fno=00006 name=/home/ora10g/oradata/roger/roger02.dbf
input datafile fno=00001 name=/home/ora10g/oradata/roger/system01.dbf
input datafile fno=00003 name=/home/ora10g/oradata/roger/sysaux01.dbf
input datafile fno=00004 name=/home/ora10g/oradata/roger/users01.dbf
input datafile fno=00008 name=/home/ora10g/oradata/roger/sqlt_01.dbf
input datafile fno=00007 name=/home/ora10g/oradata/roger/test1.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:01:25
channel ORA_DISK_1: starting full datafile backupset
channel ORA_DISK_1: specifying datafile(s) in backupset
including current control file in backupset
including current SPFILE in backupset
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03
Finished backup at 05-MAR-12
++++++ alert log ++++++

Mon Mar 05 18:30:19 PST 2012
Error backing up file 6, block 28572: logical corruption
Mon Mar 05 18:30:38 PST 2012
Hex dump of (file 6, block 50403) in trace file /home/ora10g/admin/roger/udump/roger_ora_9126.trc
Corrupt block relative dba: 0x0180c4e3 (file 6, block 50403)
Completely zero block found during backing up datafile
Reread of blocknum=50403, file=/home/ora10g/oradata/roger/roger02.dbf. found same corrupt data
Reread of blocknum=50403, file=/home/ora10g/oradata/roger/roger02.dbf. found same corrupt data
Reread of blocknum=50403, file=/home/ora10g/oradata/roger/roger02.dbf. found same corrupt data
Reread of blocknum=50403, file=/home/ora10g/oradata/roger/roger02.dbf. found same corrupt data
Reread of blocknum=50403, file=/home/ora10g/oradata/roger/roger02.dbf. found same corrupt data
Error backing up file 6, block 51684: logical corruption

SQL> set lines 150
SQL> col segment_name for a15
SQL> col owner for a20

SQL>  SELECT tablespace_name, segment_type, owner, segment_name
  2     FROM dba_extents
  3    WHERE file_id = 6
  4      AND 28572
  5  BETWEEN block_id AND block_id + blocks - 1;


TABLESPACE_NAME                SEGMENT_TYPE       OWNER                SEGMENT_NAME
------------------------------ ------------------ -------------------- ---------------
ROGER                          INDEX              ROGER                IDX_ID
这里可以看到,目前构造出了2个逻辑坏块。file 6 block 50403/51684 是以前实验留下的,不用管。

评论

  1. 很好,很强大!
    学习了。。。

  2. File recovery is a important stuff. Sadly most people don’t seem to think about it until they need it which can often be too late.

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注