InnoDB行存储的三个组成部分(说明: F字符表示列的数量)
| 名称(Name) | 大小(Size) |
| Field Start Offsets | (F*1) or (F*2) bytes |
| Extra Bytes | 6 bytes |
| Field Contents | 取决于内容 |
1: FIELD START OFFSETS指在实际数据存储行中每一字段(entry,实际存储不只是包括列,还有额外信息)的位置偏移量信息列表,这个位置由原点(Origin)相对位置和下一个字段计算而来。该列表保存的行中每一字段的偏移信息为倒序的,也就是说行中第一字段信息在这个列表的最后。举个例子:假设有三个列,第一个列的长度为1字节,第二个为2字节,第三个为4字节,这种情况下,保存三个列的偏移信息分别为[1,3(1+2),7(1+2+4)],列表倒序,转储的Field Start Offsets的信息应该为[07,03,01].有两种的特殊复杂情况:1:偏移量数字可能为一个或两个字节,一个字节最多允许长度为127,最高位bit用来保存是否为NULL,"Extra Bytes"部分说明了偏移量为一个字节还是两个字节。2:偏移量可能有一个标志信息,剩下的字节空间包含两个段,指具体的内容。(可能这些内容并不在同一个页中,参考后面的分析)当偏移量为一个字节时:1 bit = NULL7 bit, 实际的偏移信息当偏移量为两个字节时:1 bit = NULL1 bit = 0 内容在同一个页中,= 1 内容在不同的页中14 bits = 实际的偏移量,0 ~ 163832:EXTRA BYTESExtra Bytes为6个字节
| Name | Size | Description |
| info_bits: | ?? | ?? |
| () | 1 bit | 未使用 |
| () | 1 bit | 未使用 |
| deleted_flag | 1 bit | 1:删除标志位(已删除) |
| min_rec_flag | 1 bit | 1: 预定义的最小记录 |
| n_owned | 4 bits | 拥有的记录数量 |
| heap_no | 13 bits | 堆块中索引的数据页序列编号 |
| n_fields | 10 bits | 记录中的字段数量 1 to 1023 |
| 1byte_offs_flag | 1 bit | 1:Field Start Offsets为一个字节,否则为两个字节 |
| next 16 bits | 16 bits | 下一个记录的指针(System Column #1) |
| TOTAL | 48 bits | ?? |
共48 bit,6个字节如果需要通过字节读取这存储的记录,最关键的需要读取Extra Bytes 中的byte_offs_flag位信息,需要知道1表示偏移信息为一个字节,0表示两个字节如果给定了一个相对原点(Origin),InnoDB获取记录开始遵循如下步骤:-- X = n_fields,这个数字等于Field Start Offsets列表中的定义的数量-- 如果byte_offs_flag = 0,X = X * 2,每个偏移量为两个字节表示的-- X = X + 6,固定大小的Extra Bytes为6字节-- 记录的开始位置当前的位置减去X(参照FIELD CONTENTS) 3:FIELD CONTENTSField Contents部分包括了记录的所有数据,这些字段按照我们预定义的方式按顺序存储。字段与字段没有任何标记,记录的结尾也没有任何标志。实例: -- 创建一张表
CREATE TABLE T
(FIELD1 VARCHAR(3), FIELD2 VARCHAR(3), FIELD3 VARCHAR(3))
Type=InnoDB;需要知道的是,InnoDB下表中的每一行有6个字段,并不是3个,因为InnoDB在存储的内容前自动补充的3个列("system columns"),这些列分别为 行ID(row ID,该表未定义主键),事务ID(transaction ID), 回滚指针(rollback pointer)。 -- 为该表增加三条数据
INSERT INTO T VALUES ("PP", "PP", "PP");
INSERT INTO T VALUES ("Q", "Q", "Q");
INSERT INTO T VALUES ("R", NULL, NULL);运行工具(Borland"s TDUMP)查看二进制的事务文件信息(mysqldataibdata1)
| Address Values in Hexadecimal | Values in ASCII |
0D4280: 00 00 2D 00 84 4F 4F 4F 4F 4F 4F 4F 4F 4F 19 17 | ..-..OOOOOOOOO.. |
0D4290: 15 13 0C 06 00 00 78 0D 02 BF 00 00 00 00 04 21 | ......x........! |
0D42A0: 00 00 00 00 09 2A 80 00 00 00 2D 00 84 50 50 50 | .....*....-..PPP |
0D42B0: 50 50 50 16 15 14 13 0C 06 00 00 80 0D 02 E1 00 | PPP............. |
0D42C0: 00 00 00 04 22 00 00 00 00 09 2B 80 00 00 00 2D | ....".....+....- |
0D42D0: 00 84 51 51 51 94 94 14 13 0C 06 00 00 88 0D 00 | ..QQQ........... |
0D42E0: 74 00 00 00 00 04 23 00 00 00 00 09 2C 80 00 00 | t.....#.....,... |
0D42F0: 00 2D 00 84 52 00 00 00 00 00 00 00 00 00 00 00 | .-..R........... |
做一下格式处理,添加标记:
19 17 15 13 0C 06 Field Start Offsets /* First Row */
00 00 78 0D 02 BF Extra Bytes
00 00 00 00 04 21 System Column #1
00 00 00 00 09 2A System Column #2
80 00 00 00 2D 00 84 System Column #3
50 50 Field1 "PP"
50 50 Field2 "PP"
50 50 Field3 "PP"16 15 14 13 0C 06 Field Start Offsets /* Second Row */
00 00 80 0D 02 E1 Extra Bytes
00 00 00 00 04 22 System Column #1
00 00 00 00 09 2B System Column #2
80 00 00 00 2D 00 84 System Column #3
51 Field1 "Q"
51 Field2 "Q"
51 Field3 "Q"94 94 14 13 0C 06 Field Start Offsets /* Third Row */
00 00 88 0D 00 74 Extra Bytes
00 00 00 00 04 23 System Column #1
00 00 00 00 09 2C System Column #2
80 00 00 00 2D 00 84 System Column #3
52 Field1 "R" -- "Field Start Offsets" 参照First Row,从Extra Bytes开始的7个字段,大小分别为6, 6, 7, 2, 2, 2,偏移信息指向了下一字段的开始位置,16进制表示下的数字06, 0c (6+6), 13 (6+6+7), 15 (6+6+7+2), 17 (6+6+7+2+2), 19 (6+6+7+2+2+2),倒序的Field Start Offsets值分别为:[19,17,15,13,0c,06] -- "Extra Bytes" 参照First Row,Extra Bytes为[00 00 78 0D 02 BF],参照EXTRA BYTES读取跳过头21 bit读(n_fields),取10个bit,读取第三个字节最后三个个bit [000]和第四个字节0D[00001101]的7个bit [0000110],得出的6即为字段的数量(除去Extra Bytes),第四个字节0D[00001101]最后bit:1表示byte_offs_flag说明偏移量为1字节,最后的第5,6字节02 BF,指向下一行Second Row(System Column #1)的记录(02BF为0D42BF页内地址),下一记录指向了System Column #1,读取过程遵循EXTRA BYTES末的规则。 -- NULL列的表示 参照Third Row,FIELD2和FIELD3为NULL,因为byte_offs_flag为1,因此,在Field Start Offsets中[94 94 14 13 0C 06]每次读取1个字节可表示字段的偏移信息,这个字节最高位为NULL标记,14 13表示1个字节[52]的FIELD1值"R",94 14表示0字节的FIELD2值NULL(94最高位为1表示NULL,其余7 bit为14),94 94表示0字节的FIELD3值NULL。MySQL InnoDB表--BTree基本数据结构 http://www.linuxidc.com/Linux/2015-12/126151.htm在MySQL的InnoDB存储引擎中count(*)函数的优化 http://www.linuxidc.com/Linux/2015-09/123494.htmMySQL InnoDB存储引擎锁机制实验 http://www.linuxidc.com/Linux/2013-04/82240.htmInnoDB存储引擎的启动、关闭与恢复 http://www.linuxidc.com/Linux/2013-06/86415.htmMySQL InnoDB独立表空间的配置 http://www.linuxidc.com/Linux/2013-06/85760.htmMySQL Server 层和 InnoDB 引擎层 体系结构图 http://www.linuxidc.com/Linux/2013-05/84406.htmInnoDB 死锁案例解析 http://www.linuxidc.com/Linux/2013-10/91713.htmMySQL Innodb独立表空间的配置 http://www.linuxidc.com/Linux/2013-06/85760.htm
本文永久更新链接地址