Dump 分支块

drop table test;

create table test(goodid char(8),OBJECT_NAME varchar(100));


insert into test select a.object_id,a.object_name from  warecountd a

SQL> desc test;
Name        Type          Nullable Default Comments 
----------- ------------- -------- ------- -------- 
GOODID      CHAR(8)       Y                         
OBJECT_NAME VARCHAR2(100) Y  

2.    B树索引的内部结构

我们可以使用如下方式将B树索引转储成树状结构的形式而呈现出来:

SQL> select min(goodid),min(to_number(goodid)),max(goodid),max(to_number(goodid)) from test;
MIN(GOODID) MIN(TO_NUMBER(GOODID)) MAX(GOODID) MAX(TO_NUMBER(GOODID))
----------- ---------------------- ----------- ----------------------
50000                        50000 88992                        88992

创建索引:
create index IDX_WARECOUNTD_GOODID on test(goodid);

SQL> create index IDX_WARECOUNTD_GOODID on test(goodid);
Index created


收集统计信息:
BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'TEST',
                                tabname          => 'TEST',
                                estimate_percent => 100,
                                method_opt       => 'for all columns size repeat',
                                no_invalidate    => FALSE,
                                degree           => 8,
                                cascade          => TRUE);
END;


我们可以使用如下方式将B树索引转储成树状结构的形式而呈现出来:

alter session set events 'immediate trace name treedump level INDEX_OBJECT_ID';


比如,对于上面的例子来说,我们把创建在goodid上的名为idx_warecountd_goodid的索引转储出来。

SQL> select object_id from user_objects where object_name='IDX_WARECOUNTD_GOODID';

 OBJECT_ID
----------
     89037
	 
SQL> alter session set events 'immediate trace name treedump level 89037';
select value from v$diag_info where name='Default Trace File';

SQL> select value from v$diag_info where name='Default Trace File';

VALUE
--------------------------------------------------------------------------------
/oracle/app/diag/rdbms/serv/serv/trace/serv_ora_30132.trc

alter session set events 'immediate trace name treedump level 89037';


/oracle/app/diag/rdbms/serv/serv/trace/serv_ora_30132.trc


----- begin tree dump
branch: 0x103151b 16979227 (0: nrow: 7, level: 2)
   branch: 0x1031735 16979765 (-1: nrow: 419, level: 1)
      leaf: 0x103151c 16979228 (-1: nrow: 359 rrow: 359)
      leaf: 0x103151d 16979229 (0: nrow: 359 rrow: 359)
      leaf: 0x103151e 16979230 (1: nrow: 359 rrow: 359)
      leaf: 0x103151f 16979231 (2: nrow: 359 rrow: 359)
      leaf: 0x1031520 16979232 (3: nrow: 359 rrow: 359)
      leaf: 0x1031521 16979233 (4: nrow: 359 rrow: 359)
      leaf: 0x1031522 16979234 (5: nrow: 359 rrow: 359)
      leaf: 0x1031523 16979235 (6: nrow: 359 rrow: 359)
      leaf: 0x1031524 16979236 (7: nrow: 359 rrow: 359)
      leaf: 0x1031525 16979237 (8: nrow: 359 rrow: 359)
	  
	  
branch: 0x10318e0 16980192 (0: nrow: 420, level: 1)
      leaf: 0x1031734 16979764 (-1: nrow: 359 rrow: 359)
      leaf: 0x1031736 16979766 (0: nrow: 359 rrow: 359)
      leaf: 0x1031737 16979767 (1: nrow: 359 rrow: 359)
      leaf: 0x1031738 16979768 (2: nrow: 359 rrow: 359)
      leaf: 0x1031739 16979769 (3: nrow: 359 rrow: 359)
      leaf: 0x103173a 16979770 (4: nrow: 359 rrow: 359)
      leaf: 0x103173b 16979771 (5: nrow: 359 rrow: 359)
      leaf: 0x103173c 16979772 (6: nrow: 359 rrow: 359)
	  
	  0x1031734 16进制 转换为16979764
	  
	  0x10318e0  16进制 转换为 16980192
	  
	  
其中,每一行的第一列表示节点类型:branch表示分支节点(包括根节点),而leaf则表示叶子节点;
		  
第二列表示十六进制表示的节点的地址;第三列表示十进制表示的节点的地址;

		  
第四列表示相对于前一个节点的位置,根节点从0开始计算,其他分支节点和叶子节点从-1开始计算;

第五列的nrow表示当前节点中所含有的索引条目的数量。比如我们可以看到根节点中含有的nrow为9,
表示根节点中含有9个索引条目,分别指向9个分支节点;第六列中的level表示分支节点的层级,
对于叶子节点来说level都是0。第六列中的rrow表示有效的索引条目(因为索引条目如果被删除,不会立即被清除出索引块中。

所以nrow减rrow的数量就表示已经被删除的索引条目数量)的数量,比如对于第一个leaf来说,其rrow为359,

也就是说该叶子节点中存放了359个可用索引条目,分别指向表warecountd的359条记录。
		  
 上面这种方式以树状形式转储整个索引。同时,我们可以转储一个索引节点来看看其中存放了些什么。转储的方式为:
 
 我们从上面转储结果中的第二行知道,索引的根节点的地址为16979227,因此我们先将其转换为文件号以及数据块号
 
 select dbms_utility.data_block_address_file(16979227), dbms_utility.data_block_address_block(16979227) from dual;

DBMS_UTILITY.DATA_BLOCK_ADDRES DBMS_UTILITY.DATA_BLOCK_ADDRES
 
 
 
SQL> set linesize 200
SQL> set pagesize 200
SQL> select dbms_utility.data_block_address_file(16979227),
       dbms_utility.data_block_address_block(16979227)
  from dual;  2    3  

DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(16979227) DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(16979227)
---------------------------------------------- -----------------------------------------------
					     4						202011

select value from v$diag_info where name='Default Trace File';
						 
alter system dump datafile 4 block 202011;

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn 0x0000.0023604a
Branch block dump
=================
header address 140001912396364=0x7f54bc419a4c
kdxcolev 2
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 6
kdxcofbo 40=0x28
kdxcofeo 7952=0x1f10
kdxcoavs 7912
kdxbrlmc 16979765=0x1031735
kdxbrsno 0
kdxbrbksz 8056 
kdxbr2urrc 0
row#0[8039] dba: 16980192=0x10318e0
col 0; len 8; (8):  35 34 37 30 30 20 20 20 --54700
col 1; len 3; (3):  01 03 8a
row#1[8022] dba: 16980621=0x1031a8d
col 0; len 8; (8):  35 39 34 31 32 20 20 20  --59412
col 1; len 3; (3):  01 03 88
row#2[8005] dba: 16981176=0x1031cb8
col 0; len 8; (8):  36 34 31 32 34 20 20 20
col 1; len 3; (3):  01 03 85
row#3[7987] dba: 16981603=0x1031e63
col 0; len 8; (8):  36 38 38 33 39 20 20 20
col 1; len 4; (4):  01 03 82 c9
row#4[7969] dba: 16982031=0x103200f
col 0; len 8; (8):  38 30 37 34 35 20 20 20
col 1; len 4; (4):  01 03 7f 88
row#5[7952] dba: 16982245=0x10320e5
col 0; len 8; (8):  38 35 34 35 36 20 20 20
col 1; len 3; (3):  01 03 8d
----- end of branch block dump -----
End dump data blocks tsn: 4 file#: 4 minblk 202011 maxblk 202011

其中的kdxcolev表示索引层级号,这里由于我们转储的是根节点,所以其层级号为2

kdxconro表示当前索引节点中索引条目的数量

每个索引条目都指向一个分支节点。其中col 1表示所链接的分支节点的地址,该值经过一定的转换以后实际就是row#所在行的dba的值。

row#0[8039] dba: 16980192=0x10318e0

                  10进制  16进制
				  
col 0; len 8; (8):  35 34 37 30 30 20 20 20

则将其中每对值都使用函数to_number(NN,’XX’)的方式从十六进制转换为十进制

转换                53 52 55 48 48 32 32 32

于是我们得到转换后的值:53 52 55 48 48 32 32 32,因为我们已经知道索引键值是char类型的,
                         5  4  7  0 0 

所以对每个值都运用chr函数就可以得到被索引键值为:54700。

通过存储过程转换
col 0; len 8; (8):  35 34 37 30 30 20 20 20
col 1; len 3; (3):  01 03 8a

DECLARE
  n VARCHAR2(2000);
BEGIN
  DBMS_STATS.convert_raw_value('35', n);
  DBMS_OUTPUT.put_line(n);
  DBMS_STATS.convert_raw_value('34', n);
  DBMS_OUTPUT.put_line(n);
  DBMS_STATS.convert_raw_value('37', n);
  DBMS_OUTPUT.put_line(n);
  DBMS_STATS.convert_raw_value('30', n);
  DBMS_OUTPUT.put_line(n);
  DBMS_STATS.convert_raw_value('30', n);
  DBMS_OUTPUT.put_line(n);
  DBMS_STATS.convert_raw_value('20', n);
  DBMS_OUTPUT.put_line(n);
  DBMS_STATS.convert_raw_value('20', n);
  DBMS_OUTPUT.put_line(n);
  DBMS_STATS.convert_raw_value('20', n);
  DBMS_OUTPUT.put_line(n);

END;

转换出来为54700

select dump('54700') from dual;

Typ=96 Len=5: 53,52,55,48,48

54700 col 0; len 8; (8):  35 34 37 30 30 20 20 20 的最小键值


转换后的值为
54700,59412,64124,68836

原文地址:https://www.cnblogs.com/hzcya1995/p/13348386.html