[20190910]索引分支块中TERM使用什么字符表示.txt
[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的更多相关文章
- MyISAM的前缀压缩索引在索引块中的组织方式
纯粹自己的理解,哪位大佬看到了还请指正. 首先贴一张<高性能MySQL>中的一段话: 这句话的意思是说,MyISAM使用b+树组织索引.也就是说无论索引压缩与否,组织方式一定是B+树. 下 ...
- 谈数据库索引和Sqlite中索引的使用
要使用索引对数据库的数据操作进行优化,那必须明确几个问题:1.什么是索引2.索引的原理3.索引的优缺点4.什么时候需要使用索引,如何使用围绕这几个问题,来探究索引在数据库操作中所起到的作用. 1.数据 ...
- 九、dbms_ddl(提供了在PL/SQL块中执行DDL语句的方法)
1.概述 作用:提供了在PL/SQL块中执行DDL语句的方法,并且也提供了一些DDL的特殊管理方法. 2.包的组成 1).alter_compile说明:用于重新编译过程.函数和包语法:dbms_dd ...
- 孤荷凌寒自学python第三十二天python的代码块中的异常的捕获
孤荷凌寒自学python第三十二天python的代码块中的异常的捕获 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天简单了解了Python的错误陷阱,了解到其与过去学过的其它语言非常类似 ...
- 在MVC视图的代码块中,直接输出文本,有几种方式?
@{ <div>我爱IT,我是程序员,我骄傲---</div> <!--在C#代码块中,输出文本--> <!--1.0 使用Razor内置标签text--&g ...
- finally块中的代码一定会执行吗?
在Sun Tutorial中有这样一句话:The finally block always executes when the try block exits. This ensures that t ...
- [改善Java代码]不要在finally块中处理返回值
在finally代码块中处理返回值,这是在面试题中经常出现的题目.但是在项目中绝对不能再finally代码块中出现return语句,这是因为这种处理方式非常容易产生"误解",会严重 ...
- Verilog-FPGA硬件电路设计之一——if语句优先级(always块中的阻塞赋值生成的组合逻辑电路是按照顺利执行的)
出处:http://bbs.ednchina.com/BLOG_ARTICLE_3013262.HTM 综合软件:Quartus II 一.有优先级的if语句 if..else if.. else i ...
- 一个问题:关于finally中return吞掉catch块中抛出的异常
今天遇到一个感觉很神奇的问题,记录一下问题以及自己分析问题的思路. 预警:不知道怎么看java字节码的朋友可能需要先看一下如何阅读java字节码才能看懂后面的解释. 我有一段程序: public cl ...
随机推荐
- kmeans均值聚类算法实现
这个算法中文名为k均值聚类算法,首先我们在二维的特殊条件下讨论其实现的过程,方便大家理解. 第一步.随机生成质心 由于这是一个无监督学习的算法,因此我们首先在一个二维的坐标轴下随机给定一堆点,并随即给 ...
- OpenCV:图像平滑和图像模糊处理
导包: import numpy as np import cv2 import matplotlib.pyplot as plt def show(image): plt.imshow(image) ...
- postman---postman生成测试报告
做完测试后,都会编写一份测试报告,测试报告中最主要的就是呈现出测试结果,哪些用例通过了,哪些用例没有通过.像postman这么强大的功能也可以自动生成报告,供我们测试同学进行查看,显得更加有B格~~~ ...
- java8-07-方法引用总结
一:方法引用 如果Lambda体中的内容 已经有方法实现了 我们可以使用"方法引用" (可以理解为 ...
- 2019 SDN上机第5次作业
2019 SDN上机第5次作业 1.浏览RYU官网学习RYU控制器的安装和RYU开发入门教程,提交你对于教程代码的理解,包括但不限于: 描述官方教程实现了一个什么样的交换机功能? 答:官方教程实现了一 ...
- 打包一个python解释器
利用python的exec语句,可以很方便地动态执行python语句.如果一个python代码打包为了exe,其原先的代码就很难更改了.一个好的解决方法就是import相应的库,然后把主程序段放到一个 ...
- Note | 用Hugo搭建博客并部署到GitHub Pages
目录 1. 本地搭建 1.1 安装Hugo 1.2 创建站点 1.3 新建页面和文章 1.4 使用主题 1.5 修改配置文件 1.6 预览 2. 部署 之前担心过现有博客平台(如博客园,CSDN)突然 ...
- Python连载48-正则表达式(中)
一.正则的写法: . (点好) :表示任意一个字符,除了\n,比如查找所有的一个字符\. [] :匹配中括号中列举的任意字符,比如[L,Y,0], LLY, Y0, LIU \d :任意一个数字 \D ...
- Mybatis和Hibernate框架的区别
Mybatis和Hibernate框架的区别1 简单简介 1.1 Hibernate 框架 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,建立对象与数据 ...
- 解决root用户下都无权限操作的问题
问题现象: 有时系统设置了一种文件,无法编辑其所有权 sudo chown users:username {filename} 或者root用户下执行 chown users:username {f ...