[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
来源:这里教程网
时间:2026-03-03 14:13:07
作者:
编辑推荐:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- 华为Mate 20 Pro发布近一年,仍受追捧,四个方面告诉你原因
华为Mate 20 Pro发布近一年,仍受追捧,四个方面告诉你原因
26-03-03 - oracle快速彻底清理kill会话
oracle快速彻底清理kill会话
26-03-03 - AWR 报告深度解读:Redo Nowait指标的算法和诊断
AWR 报告深度解读:Redo Nowait指标的算法和诊断
26-03-03 - 华为手机音量键隐藏6个秘密,很少人用到,真是浪费一部好手机
华为手机音量键隐藏6个秘密,很少人用到,真是浪费一部好手机
26-03-03 - 小米手机这几个设置不关,天天清理内存都没用,关了手机更顺滑
小米手机这几个设置不关,天天清理内存都没用,关了手机更顺滑
26-03-03 - AWR 报告深度解读:Time Model Statistics 信息的计算和获取
- 还在用手机管家清理内存?删除这几个文件夹,手机瞬间多出10G
还在用手机管家清理内存?删除这几个文件夹,手机瞬间多出10G
26-03-03 - 为什么越来越多手机取消呼吸灯,没有呼吸灯是一种什么体验
为什么越来越多手机取消呼吸灯,没有呼吸灯是一种什么体验
26-03-03 - 苹果手机一键就能生成电子证件照?这么好用的功能你不会没用过吧
苹果手机一键就能生成电子证件照?这么好用的功能你不会没用过吧
26-03-03 - Oracle 20c数据库开启原生的区块链表、AutoML以及持久化内存支持
