怎样找到指定键值的index block

| No Comments

今天在和朋友讨论unique indexnon unique index的结构的时候用到了按照指定索引键值去找相应的index block,我觉得还是有必要在这里把找的方法阐述一下。

 

我是这么找的:

1、先做一个treedump

2、再根据treedump去定位branch block

3、接着根据branch block去定位leaf block

4、最后根据leaf block去找指定键值的offset

然后你就可以根据上述内容做任何事情了。

 

我们来看一个实例:

SQL> create unique index idx_testdrop2_objid on testdrop2(object_id) tablespace testtbs3;

 

Index created

 

SQL> select object_name,object_id from testdrop2 where object_id=21886;

 

OBJECT_NAME                                     OBJECT_ID

-------------------------------------------------------------------------------- ----------

sun/io/CharToByteISO8859_4                           21886

 

SQL> select object_id from dba_objects where object_name='IDX_TESTDROP2_OBJID';

 

 OBJECT_ID

----------

     86150

 

我们现在要把索引键值为21886的那个index block找出来,并计算出offset

首先做一个treedump,语法为alter session set events 'immediate trace name treedump level 86150';

dump出来的trace文件中我们可以看到branch block的地址:

branch: 0x2240028d 574620301 (0: nrow: 68, level: 1)

 

SQL> exec sys.cdba('2240028d','H');

.

The file is 137

The block is 653

 

PL/SQL procedure successfully completed

 

再把137-653这个branch block dump出来:

row#42[7688] dba: 574620345=0x224002b9

col 0; len 4; (4):  c3 03 0e 3d

row#43[7679] dba: 574620346=0x224002ba

col 0; len 4; (4):  c3 03 13 28

row#44[7670] dba: 574620347=0x224002bb

col 0; len 4; (4):  c3 03 18 13

 

SQL> select dump(21886,16) from dual;

 

DUMP(21886,16)

-----------------------

Typ=2 Len=4: c3,3,13,57

 

dump出来的结果可以看到索引键值为21886的是在0x224002ba这个block里:

SQL> exec sys.cdba('224002ba','H');

.

The file is 137

The block is 698

 

PL/SQL procedure successfully completed

 

也就是说索引键值为21886的实际上是在137-698这个block

 

137-698这个block dump出来,可以从dump出来的内容里看到:

row#47[7408] flag: -----, lock: 0, data:(6):  22 40 00 8d 00 00

col 0; len 4; (4):  c3 03 13 57

 

这里我们可以看到索引键值为21886所对应的rowid22 40 00 8d 00 00其计算出来的offset7408+76+(2-1)*24=7508

 

好了,我们来验证一下:

$ bbed parfile=par.txt

Password:

 

BBED: Release 2.0.0.0.0 - Limited Production on Tue Jun 9 17:49:58 2009

 

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

 

************* !!! For Oracle Internal Use only !!! ***************

 

BBED> set file 137

        FILE#           137

 

BBED> set block 698

        BLOCK#          698

 

BBED> set offset 7508

        OFFSET          7508

 

BBED> dump

 File: /dras20/astca/testtbs3_01.dbf (137)

 Block: 698              Offsets: 7508 to 8019           Dba:0x224002ba

------------------------------------------------------------------------

 00002240 008d0000 04c30313 57000022 40013100 0704c303 13560000 224000c8

 004804c3 03135500 00224001 31000604 c3031354 00002240 00c80047 04c30313

 53000022 40015200 3704c303 13520000 224001c7 003904c3 03135100 00224001

 31000504 c3031350 00002240 00c80046 04c30313 4f000022 40013100 0404c303

 134e0000 224000c8 004504c3 03134d00 00224001 31000304 c303134c 00002240

 00c80044 04c30313 4b000022 40013100 0204c303 134a0000 224000c8 004304c3

 03134900 00224001 31000104 c3031348 00002240 00c80042 04c30313 47000022

 40013100 0004c303 13460000 224000c8 004104c3 03134500 00224001 2d004804

 c3031344 00002240 00c80040 04c30313 43000022 40012d00 4704c303 13420000

 224000c8 003f04c3 03134100 00224001 2d004604 c3031340 00002240 00c8003e

 04c30313 3f000022 40012d00 4504c303 133e0000 224000c8 003d04c3 03133d00

 00224001 2d004404 c303133c 00002240 00c8003c 04c30313 3b000022 40012d00

 3f04c303 133a0000 224000c8 003704c3 03133900 00224001 2d003e04 c3031338

 00002240 00c80036 04c30313 37000022 40012d00 3d04c303 13360000 224000c8

 003504c3 03133500 00224001 2d003c04 c3031334 00002240 00c80034 04c30313

 33000022 40012d00 3b04c303 13320000 224000c8 003304c3 03133100 00224001

 

 <32 bytes per line>

 

这里我们可以直观的看到对于unique index而言,rowid是存在行头的。

在我写的"人为制造数据不一致一例"里,可以看到对于non unique index而言,rowid并没有存在行头,而是单独存成了一个column

Leave a comment