[20190910]索引分支块中TERM使用什么字符表示.txt

--//做索引块转储,一些root,分支节点出现TERM,从来没有关注使用字符表示,简单探究看看。

1.环境:
SCOTT@test01p> @ ver1

PORT_STRING                    VERSION        BANNER                                                                               CON_ID
------------------------------ -------------- -------------------------------------------------------------------------------- ----------
IBMPC/WIN_NT64-9.1.0           12.2.0.1.0     Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production              0

SCOTT@test01p> create table t as select to_char(rownum,'FM'||lpad('0',20,'0')) v1 from dual connect by level<=2000;
Table created.

SCOTT@test01p> create index i_t_v1 on t(v1);
Index created.

SCOTT@test01p> select header_file,header_block from dba_segments where owner=user and segment_name='I_T_V1';
HEADER_FILE HEADER_BLOCK
----------- ------------
         11          506

SCOTT@test01p> @ treedump i_t_v1
old   1: select object_id from user_objects where object_name = upper('&&1') and object_type = 'INDEX'
new   1: select object_id from user_objects where object_name = upper('i_t_v1') and object_type = 'INDEX'
 OBJECT_ID
----------
     27931

old   1: alter session set events 'immediate trace name treedump level &m_index_id'
new   1: alter session set events 'immediate trace name treedump level      27931'
Session altered.

2.检查转储:
--//转储内容:
----- begin tree dump
branch: 0x2c001fb 46137851 (0: nrow: 9, level: 1)

*** 2019-09-10T20:55:45.660043+08:00 (TEST01P(3))
   leaf: 0x2c001fc 46137852 (-1: row:224.224 avs:832)
   leaf: 0x2c001fd 46137853 (0: row:224.224 avs:832)
   leaf: 0x2c001fe 46137854 (1: row:224.224 avs:832)
   leaf: 0x2c001ff 46137855 (2: row:224.224 avs:832)
   leaf: 0x2c003e0 46138336 (3: row:224.224 avs:832)
   leaf: 0x2c003e1 46138337 (4: row:224.224 avs:832)
   leaf: 0x2c003e2 46138338 (5: row:224.224 avs:832)
   leaf: 0x2c003e3 46138339 (6: row:224.224 avs:832)
   leaf: 0x2c003e4 46138340 (7: row:208.208 avs:1344)
----- end tree dump

--//0x2c001fb  = set dba 11,507 = alter system dump datafile 11 block 507
--//转储root节点.

SCOTT@test01p> alter system checkpoint ;
System altered.

SCOTT@test01p> alter system dump datafile 11 block 507;
System altered.

--//转储内容:
Block header dump:  0x02c001fb
 Object id on Block? Y
 seg/obj: 0x6d1b  csc:  0x0000000000a2b4d9  itc: 1  flg: E  typ: 2 - INDEX
     brn: 0  bdba: 0x2c001f8 ver: 0x01 opc: 0
     inc: 0  exflg: 0
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn  0x0000000000a2b4d9
Branch block dump
=================
header address 629538892=0x2586004c
kdxcolev 1
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 8
kdxcofbo 44=0x2c
kdxcofeo 7852=0x1eac
kdxcoavs 7808
kdxbrlmc 46137852=0x2c001fc
kdxbrsno 0
kdxbrbksz 8060
kdxbr2urrc 0
row#0[8034] dba: 46137853=0x2c001fd
col 0; len 20; (20):  30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 32 35
--//30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 32 35 = 00000000000000000225
col 1; TERM
--//出现TERM.
row#1[8008] dba: 46137854=0x2c001fe
col 0; len 20; (20):  30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 34 34 39
col 1; TERM
row#2[7982] dba: 46137855=0x2c001ff
col 0; len 20; (20):  30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 36 37 33
col 1; TERM
row#3[7956] dba: 46138336=0x2c003e0
col 0; len 20; (20):  30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 38 39 37
col 1; TERM
row#4[7930] dba: 46138337=0x2c003e1
col 0; len 20; (20):  30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 31 32 31
col 1; TERM
row#5[7904] dba: 46138338=0x2c003e2
col 0; len 20; (20):  30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 33 34 35
col 1; TERM
row#6[7878] dba: 46138339=0x2c003e3
col 0; len 20; (20):  30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 35 36 39
col 1; TERM
row#7[7852] dba: 46138340=0x2c003e4
col 0; len 20; (20):  30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 31 37 39 33
col 1; TERM
----- end of branch block dump -----
End dump data blocks tsn: 4 file#: 11 minblk 507 maxblk 507

--//转储可以发现TERM,表示终结,也就是叶子节点并不需要保存完整键值,仅仅部分就ok了。
--//当然这里看不出来TERM的对应编码.看转储文件前面的内容如下:

Dump of memory from 0x0000000025860000 to 0x0000000025862000
025860000 0000A206 02C001FB 00A2B4DD 04010000  [................]
025860010 0000AFCD 00000002 00006D1B 00A2B4D9  [.........m......]
025860020 00008000 00320001 02C001F8 0000FFFF  [......2.........]
025860030 00000000 00000000 00000000 80008000  [................]
025860040 00A2B4D9 00000000 00000000 02800001  [................]
025860050 00000000 002C0008 1E801EAC 02C001FC  [......,.........]
025860060 00000000 00001F7C 1F481F62 1F141F2E  [....|...b.H.....]
025860070 1EE01EFA 1EAC1EC6 00000000 00000000  [................]
025860080 00000000 00000000 00000000 00000000  [................]
        Repeat 486 times
025861EF0 00000000 00000000 02C003E4 30303014  [.............000]
025861F00 30303030 30303030 30303030 39373130  [0000000000000179]
025861F10 03E3FE33 301402C0 30303030 30303030  [3......000000000]
025861F20 30303030 31303030 FE393635 02C003E2  [00000001569.....]
025861F30 30303014 30303030 30303030 30303030  [.000000000000000]
025861F40 34333130 03E1FE35 301402C0 30303030  [01345......00000]
025861F50 30303030 30303030 31303030 FE313231  [000000000001121.]
025861F60 02C003E0 30303014 30303030 30303030  [.....00000000000]
025861F70 30303030 39383030 01FFFE37 301402C0  [000000897......0]
025861F80 30303030 30303030 30303030 30303030  [0000000000000000]
025861F90 FE333736 02C001FE 30303014 30303030  [673......0000000]
025861FA0 30303030 30303030 34343030 01FDFE39  [0000000000449...]
025861FB0 301402C0 30303030 30303030 30303030  [...0000000000000]
025861FC0 30303030 FE353232 00000000 00000000  [0000225.........]
                   ~~~~~~~~
025861FD0 00000000 00000000 00000000 00000000  [................]
        Repeat 1 times
025861FF0 00000000 00000000 00000000 B4DD0601  [................]

--//注意看下划线内容可以知道term对应编码是0xfe.
--//当然我的例子特殊,如果上面的索引建立唯一索引就不会出现这样的情况,因为这样rowid在索引键值的前面。

3.bbed观察看看:
BBED> set dba 11,508
        DBA             0x02c001fc (46137852 11,508)
--//注:windows下的bbed块出现偏移要+1.

BBED> p kd_off
b2 kd_off[0]    @100      8060
b2 kd_off[1]    @102      0
b2 kd_off[2]    @104      8034
b2 kd_off[3]    @106      8008
b2 kd_off[4]    @108      7982
b2 kd_off[5]    @110      7956
b2 kd_off[6]    @112      7930
b2 kd_off[7]    @114      7904
--//bbed看索引结构有一些问题,kd_off[0],kd_off[1]指向的偏移不对.实际上从kd_off[2]开始.

BBED> x /rcx *kd_off[2]
rowdata[186]                                @8110
------------
child dba:     0x02c001fd
separator key:
col   0[20] @8115: 00000000000000000225
col    1[0] @8136: *TERM*

BBED> x /rcx *kd_off[3]
rowdata[160]                                @8084
------------
child dba:     0x02c001fe
separator key:
col   0[20] @8089: 00000000000000000449
col    1[0] @8110: *TERM*
---//这里的偏移有问题.偏移8110是下一条记录的开始,估计是bbed的bug.

BBED> dump /v offset 8110
 File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
 Block: 508                               Offsets: 8110 to 8191                            Dba:0x02c001fc
-----------------------------------------------------------------------------------------------------------
 fd01c002 14303030 30303030 30303030 30303030 30303232 35fe0000 00000000 l ??.00000000000000000225?.....
 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 l ................................
 00000000 00000000 00000000 00000106 ddb4                                l ................荽
 <32 bytes per line>

BBED> x /rcx offset 8110
rowdata[186]                                @8110
------------
child dba:     0x02c001fd
separator key:
col   0[20] @8115: 00000000000000000225
col    1[0] @8136: *TERM*

BBED> dump /v offset 8109 count 2
 File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
 Block: 508                               Offsets: 8109 to 8110                            Dba:0x02c001fc
-----------------------------------------------------------------------------------------------------------
 fefd                                                                    l 
 <32 bytes per line>

--//bbed显示的x命令显示col 1的偏移有问题,实际上列长度是0.偏移8110是另一条记录.
--//可以发现TERM实际上对应ASCII码是0xfe。这样就很好解析我以前遇到的问题。链接:
--//http://blog.itpub.net/267265/viewspace-1291526/=>[20141008]索引字符串的长度问题.txt

--//对于索引字符串的长度:
--//1.当字符串长度小于等于127时,使用1个字节表示长度.
--//2.当字符串大于等于128时,使用2个字节来保存长度,内容为字符串长度+0x8000.
--//3.真搞不懂为什么与数据块的保存方式不同,oracle要创造2种不同的方式保存字符串.

--//当时很不理解为什么oracle要创造2种不同的方式保存字符串,现在明白了。

--//曾经写过一篇"varchar2(4000)如何保存",链接如下:
--//http://blog.itpub.net/267265/viewspace-2148818/ => [20171218]varchar2(4000)如何保存.txt

--//如果一行能被存储于一个数据块(data block)中,那么其行头(row header)所需容量将不少于 3 字节(byte)。在行头信息之后依次储存
--//的是各列的列长(column length)及列值(column value)。列长存储于列值之前,如列值不超过250 字节,那么 Oracle使用1字节存储其
--//列长;如列值超过 250 字节,则使用 3 字节存储其列长。列数据(column data)所需的存储空间取决于此列的数据类型(datatype)。如
--//果某列的数据类型为变长(variable length)的,那么存储此列值所需的空间可能会随着数据更新而增长或缩小。

--//当时的总结:
--//1.如果列值长度小于等于250字节,Oracle使用1字节存储其列长.内容为字段的长度.
--//2.如果列值长度超过250字节,则使用3字节存储其列长。前面1个字节使用0xfe(表示超过250),后面2个字节表示列值长度.

--//很明显0xfe在数据块中的字符串长度指示器一部分,用来表示保存字符超过250字节。而索引TERM使用0xfe表示。
--//这样索引字段字符串长度如果大于250,就不能再使用数据块中类似的方式保存键值长度。这样oraclea必须采用新的模式定义索引中字符串长度.
--//语言不好表达,还是通过例子说明:

4.继续测试:
create table t1 (v1 varchar2(4000));
insert into t1 values (lpad('1',127,'1'));
insert into t1 values (lpad('2',128,'2'));
insert into t1 values (lpad('3',4000,'3'));
commit ;
create index i_t1_v1 on t1(v1);
alter system checkpoint ;

SCOTT@test01p> select header_file,header_block from dba_segments where owner=user and segment_name='I_T1_V1';
HEADER_FILE HEADER_BLOCK
----------- ------------
         11          410

--//索引根节点在11,411.通过bbed观察:

BBED> set dba 11,412
        DBA             0x02c0019c (46137756 11,412)

BBED> p kd_off
b2 kd_off[0]  @132      8036
b2 kd_off[1]  @134      0
b2 kd_off[2]  @136      7899

BBED> x /rcx *kd_off[2]
rowdata[4154]                               @7999
-------------
flag@7999:     0x00 (NONE)
lock@8000:     0x00
data key:
col  0[127] @8002: 11111111...1111111111
col    1[6] @8130:  0x02  0xc0  0x01  0x95  0x00  0x00

BBED> dump /v offset 8001 count 10
 File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
 Block: 412                               Offsets: 8001 to 8010                            Dba:0x02c0019c
-----------------------------------------------------------------------------------------------------------
 7f313131 31313131 3131                                                  l .111111111
<32 bytes per line>

--//7f = 127 ,使用1个字节表示字符串长度.

BBED> dump /v offset 138 count 4
 File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
 Block: 412                               Offsets:  138 to  141                            Dba:0x02c0019c
-----------------------------------------------------------------------------------------------------------
 501ea50e                                                                l P.?
<32 bytes per line>

--//字节颠倒顺序 0x1e50 = 7760, 0x0ea5 = 3749 .相对偏移在7760,3749,看前面kd_off[2]偏移可以看出绝对偏移要加100.

BBED> x /rcx offset 7860
rowdata[4015]                               @7860
-------------
flag@7860:     0x00 (NONE)
lock@7861:     0x00
data key:
col  0[128] @7864: 22222...22222
col    1[6] @7993:  0x02  0xc0  0x01  0x95  0x00  0x01

BBED> dump /v offset 7862 count 10
 File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
 Block: 412                               Offsets: 7862 to 7871                            Dba:0x02c0019c
-----------------------------------------------------------------------------------------------------------
 80803232 32323232 3232                                                  l ..22222222
<32 bytes per line>
--//出现2次0x80.

BBED> x /rcx offset 3849
rowdata[4]                                  @3849
----------
flag@3849:     0x00 (NONE)
lock@3850:     0x00
data key:
col 0[4000] @3853: 3333............
........3333333
col    1[6] @7854:  0x02  0xc0  0x01  0x95  0x00  0x02

BBED> dump /v offset 3851 count 10
 File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
 Block: 412                               Offsets: 3851 to 3860                            Dba:0x02c0019c
-----------------------------------------------------------------------------------------------------------
 8fa03333 33333333 3333                                                  l .?3333333
 <32 bytes per line>

--//0x8fa0 -0x8000 = 0xfa0 = 4000.

--//对于索引字符串的长度:
--//1.当字符串长度小于等于127时,使用1个字节表示长度.
--//2.当字符串大于等于128时,使用2个字节来保存长度,内容为字符串长度+0x8000.

--//以前学习oracle很不理解为什么数据块中字串长度小于等于250字节,Oracle使用1字节存储其列长.内容为字段的长度.
--//为什么把边界定义在250. 0xff用来保存空值,0xfe作为>250字串长度指示器编码一部分(在索引表示TERM).
--//按照这样的道理,oracle还预留了0xfb,0xfc,0xfd,不知道在那里会用上....

[20190910]索引分支块中TERM使用什么字符表示.txt的更多相关文章

  1. MyISAM的前缀压缩索引在索引块中的组织方式

    纯粹自己的理解,哪位大佬看到了还请指正. 首先贴一张<高性能MySQL>中的一段话: 这句话的意思是说,MyISAM使用b+树组织索引.也就是说无论索引压缩与否,组织方式一定是B+树. 下 ...

  2. 谈数据库索引和Sqlite中索引的使用

    要使用索引对数据库的数据操作进行优化,那必须明确几个问题:1.什么是索引2.索引的原理3.索引的优缺点4.什么时候需要使用索引,如何使用围绕这几个问题,来探究索引在数据库操作中所起到的作用. 1.数据 ...

  3. 九、dbms_ddl(提供了在PL/SQL块中执行DDL语句的方法)

    1.概述 作用:提供了在PL/SQL块中执行DDL语句的方法,并且也提供了一些DDL的特殊管理方法. 2.包的组成 1).alter_compile说明:用于重新编译过程.函数和包语法:dbms_dd ...

  4. 孤荷凌寒自学python第三十二天python的代码块中的异常的捕获

    孤荷凌寒自学python第三十二天python的代码块中的异常的捕获 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天简单了解了Python的错误陷阱,了解到其与过去学过的其它语言非常类似 ...

  5. 在MVC视图的代码块中,直接输出文本,有几种方式?

    @{ <div>我爱IT,我是程序员,我骄傲---</div> <!--在C#代码块中,输出文本--> <!--1.0 使用Razor内置标签text--&g ...

  6. finally块中的代码一定会执行吗?

    在Sun Tutorial中有这样一句话:The finally block always executes when the try block exits. This ensures that t ...

  7. [改善Java代码]不要在finally块中处理返回值

    在finally代码块中处理返回值,这是在面试题中经常出现的题目.但是在项目中绝对不能再finally代码块中出现return语句,这是因为这种处理方式非常容易产生"误解",会严重 ...

  8. Verilog-FPGA硬件电路设计之一——if语句优先级(always块中的阻塞赋值生成的组合逻辑电路是按照顺利执行的)

    出处:http://bbs.ednchina.com/BLOG_ARTICLE_3013262.HTM 综合软件:Quartus II 一.有优先级的if语句 if..else if.. else i ...

  9. 一个问题:关于finally中return吞掉catch块中抛出的异常

    今天遇到一个感觉很神奇的问题,记录一下问题以及自己分析问题的思路. 预警:不知道怎么看java字节码的朋友可能需要先看一下如何阅读java字节码才能看懂后面的解释. 我有一段程序: public cl ...

随机推荐

  1. Add a Class from the Business Class Library从业务类库添加类(EF)

    In this lesson, you will learn how to use business classes from the Business Class Library as is. Fo ...

  2. Angular中使用bootstrap样式

    Angular中使用bootstrap样式 Angular中引入bootstrap的方法   方法1:在Angular.json中的styles数组中添加bootstrap路径 如下所示: " ...

  3. Ubuntu16.04 安装 JDK

    1.到Oracle官网下载 地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ...

  4. Checklist for an RMAN Restore (Doc ID 1554636.1)

    Checklist for an RMAN Restore (Doc ID 1554636.1) APPLIES TO: Oracle Database - Enterprise Edition - ...

  5. [Go] go中的goto语句跳到指定标签

    比如下面的语句goto TOP ,其中TOP就是自己的自定义的标签,下面的TOP:就是要执行的代码段一般用在需要两层循环的地方,里面goto再跳回上面去 ; i < ; i++ { { goto ...

  6. WPF 绑定属性 XAML 时间格式化

    原文:WPF 绑定属性 XAML 时间格式化 XAML 时间格式化{Binding Birthday,StringFormat='yyyy-MM-dd '} public class AssetCla ...

  7. SpringBootTest MockMVC绑定session(需要登陆的接口)

    https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#testing spring-te ...

  8. SpringBatch介绍

    SpringBatch 是一个大数据量的并行处理框架.通常用于数据的离线迁移,和数据处理,⽀持事务.并发.流程.监控.纵向和横向扩展,提供统⼀的接⼝管理和任务管理;SpringBatch是Spring ...

  9. nginx--代理和负载均衡

    nginx代理 nginx的代理分为正向代理和反向代理 正向代理指的是,一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原 ...

  10. Linux下修改Mysql密码的三种方式

    前言 有时我们会忘记Mysql的密码,或者想改一个密码,以下将对这两种情况修改密码的三种解决方法做个总结 本文都以用户为 root 为例 一.拥有原来的myql的root的密码 方法一: 在mysql ...