发表于: 2006.04.23 22:01
分类: ora internal
出处: http://lawzjf.itpub.net/post/417/72620
---------------------------------------------------------------
软件版本:XP sp2,Oracle 10.2.0.1
首先创建测试表:
SQL> create table test_idx
2 as
3 select * from all_objects
4 /
表已创建。
SQL> select count(*) from test_idx;
COUNT(*)
--------------
4473
SQL> desc test_idx
名称 是否为空? 类型
---------------------------------- --------------- --------------
OWNER NOT NULL VARCHAR2(30)
OBJECT_NAME NOT NULL VARCHAR2(30)
SUBOBJECT_NAME VARCHAR2(30)
OBJECT_ID NOT NULL NUMBER
......
我们在整数列object_id上创建索引:
SQL> create index idxx on test_idx(object_id)
2 /
索引已创建。
查询新建的表和索引所在的表空间(因为自动段管理与手工管理的不同情况下,表空间中的段头所占用的block数是不同的,自动管理情况下,段头占用3个block,手工管理占用1个block):
SQL> select tablespace_name,segment_name
2 from user_segments
3 where segment_name in('TEST_IDX','IDXX')
4 /
TABLESPACE_NAME SEGMENT_NAME
------------------------------ ---------------
USERS TEST_IDX
USERS IDXX
查询users表空间的段空间管理方式:
SQL> conn system/oracle
已连接。
SQL> select tablespace_name,segment_space_management
2 from dba_tablespaces
3 where tablespace_name='USERS'
4 /
TABLESPACE_NAME SEGMEN
------------------------------ -------------
USERS AUTO
查询新建索引被分配的block情况:
SQL> col segment_name for a10
SQL> select segment_name,file_id,extent_id,block_id
2 from dba_extents
3 where segment_name='IDXX'
4 /
SEGMENT_NA FILE_ID EXTENT_ID BLOCK_ID
------------------- ------------- ---------------- ----------------
IDXX 4 0 225
IDXX 4 1 233
从上面结果可以知道,新建的索引分配到两个区,
各有8个block。因为索引所在的表空间为自动段管理,
其中的数据对象被分配的前三个block用来存储对象的
系统信息,而对象的真正数据从第4个block开始存储,
所以,idxx的数据228块开始存储。
下面,我们导出从228开始的三个数据块内容:
SQL> conn system/oracle
已连接。
SQL> alter system dump datafile 4 block min 228 block max 230;
系统已更改。
在udmp目录下查看新生成的导出文件,并打开,可以看出
228块为root节点,而229及230为两个叶节点。
摘录其内容如下(内容经过删减,但未作更改):
228号:
Branch blockdump ---表明这是一个分枝节点,其实这是root节点=================
header address 121512524=0x73e224c
kdxcolev 1 ##index level (0 represents leaf blocks)
KDXCOLEV Flags = - - -
kdxcolok 0 ##denotes whether structural block transaction is occurring
kdxcoopc 0x80: pcode=0: iot flags=--- is converted=Y ##internal operation code
kdxconco 2 ##index column count
kdxcosdc 0 ##count of index structural changes involving block
kdxconro 9 ##number of index entries (does not include kdxbrlmc pointer)
kdxcofbo 46=0x2e ##offset to beginning of free space within block
kdxcofeo 7979=0x1f2b ##offset to the end of free space (ie. first portion of block containing index data)
kdxcoavs 7933 ##available space in block (effectively area between the two fields above)
kdxbrlmc16777445=0x10000e5--这是下层节点的第 一个block号码229
kdxbrsno 0 ##last index entry to be modified
kdxbrbksz 8060 ##size of usable block space
kdxbr2urrc 0
row#0[8051] dba: 16777446=0x10000e6--块号230
col 0; len 3; (3): c2 12 30--此块中的最小的key值
col 1; TERM
row#1[8042] dba: 16777447=0x10000e7--块号
col 0; len 3; (3): c2 19 60--此块中的最小的key值
col 1; TERM
row#2[8033] dba: 16777448=0x10000e8
col 0; len 3; (3): c2 21 5f
col 1; TERM
row#3[8024] dba: 16777449=0x10000e9
col 0; len 3; (3): c2 29 49
col 1; TERM
……
row#7[7988] dba: 16777453=0x10000ed
col 0; len 3; (3): c2 54 21
col 1; TERM
row#8[7979] dba: 16777454=0x10000ee
col 0; len 3; (3): c2 64 61
col 1; TERM
----- end of branch block dump -----
可以看出,root节点下层共有10个block
相关内容的解释:
kdxcolev: index level (0 represents leaf blocks)
kdxcolok: denotes whether structural block transaction is occurring
kdxcoopc: internal operation code
kdxconco: index column count
kdxcosdc: count of index structural changes involving block
kdxconro: number of index entries (does not include kdxbrlmc pointer)
kdxcofbo: offset to beginning of free space within block
kdxcofeo: offset to the end of free space (ie. first portion of block containing index data)
kdxcoavs: available space in block (effectively area between the two fields above)
229号:
Leaf block dump
===============
header address 121512548=0x73e2264
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: pcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 479
kdxcofbo 994=0x3e2
kdxcofeo 1813=0x715
kdxcoavs 819
kdxlespl 0
kdxlende 0
kdxlenxt 16777446=0x10000e6 --下一个block号码
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 8036
row#0[8023] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 03 3b--此块中的最小key值
col 1; len 6; (6): 01 00 00 a4 00 00--rowid
row#1[8010] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 03 3c
col 1; len 6; (6): 01 00 00 a4 00 01
row#2[7997] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 04 0c
col 1; len 6; (6): 01 00 00 a4 00 02
……
row#477[1826] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 12 2e
col 1; len 6; (6): 01 00 00 a9 00 4f
row#478[1813] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 12 2f
col 1; len 6; (6): 01 00 00 aa 00 00
----- end of leaf block dump -----
230号:
Leaf block dump
===============
header address 121512548=0x73e2264
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: pcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 479
kdxcofbo 994=0x3e2
kdxcofeo 1814=0x716
kdxcoavs 820
kdxlespl 0
kdxlende 0
kdxlenxt 16777447=0x10000e7--下一个block号码
kdxleprv 16777445=0x10000e5--前一个block号码
kdxledsz 0
kdxlebksz 8036
row#0[8023] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 12 30
col 1; len 6; (6): 01 00 00 aa 00 01
row#1[8010] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 12 31
col 1; len 6; (6): 01 00 00 aa 00 02
row#2[7997] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 12 33
col 1; len 6; (6): 01 00 00 aa 00 03
……
关于rowid的换算:索引中的rowid由48个bit构成,前10个bit构成文件号,中间22个bit构成块号,最后16个bit构成块中的行号。
关于整数key值的换算:如229块中的最小key值为c2 03 3b,先去掉c2,因为c2只表示最高位的位置,后面才是真正数据,03转换为十进制为3,减去1为2,3b转换为十进制为48+11=59,减去1为58,两个结果合并到一起,为258,这就是七其存储的真正数据,简单表示一下:
- c2 03 3b -> 03 3b
- 03 -> 0*16+3=3->3-1=2
- 3b -> 3*16+14=59 -> 59-1=58
- 结果合并得到258
关于字符串的换算:直接由十六进制得到各个ascii码,然后对应到相应字符。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/263455/viewspace-750982/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/263455/viewspace-750982/