1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
mysql> show
table
status
like
't1'
\G;
*************************** 1. row ***************************
Name
: t1
Engine: InnoDB
Version: 10
Row_format: Compact
Rows
: 2
Avg_row_length: 8192
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment:
NULL
Create_time: 2016-01-11 05:04:28
Update_time:
NULL
Check_time:
NULL
Collation: utf8_general_ci
Checksum:
NULL
Create_options:
Comment:
1 row
in
set
(0.00 sec)
ERROR:
No
query specified
mysql>
|
Compact行记录的格式
-变长字段长度列表:如果列的长度小于255字节,用1字节表示;如果大于255个字节,用2字节表示
-NULL标志位:表明该行数据是否有NULL值。占一个字节。
-记录头信息:固定占用5字节,每位的含义见下表:
名称 | 大小(bit) | 描述 |
() | 1 | 未知 |
() | 1 | 未知 |
delete_flag | 1 | 该行是否已被删除 |
min_rec_flag | 1 | 为1,如果该记录是预先被定义为最小的记录 |
n_owned | 4 | 该记录拥有的记录数 |
heap_no | 13 | 索引堆中该记录的排序记录 |
record_type | 3 | 记录类型,000表示普通,001表示B+树节点指针,010表示infimum,011表示supermum,1xx表示保留 |
next_record | 16 | 页中下一条记录的相对位置 |
total | 40 |
在每个列的存储数据中,NULL不占该部分任何空间。此外还有两个隐藏列,事务ID列和回滚指针列,分别为6字节和7字节。若innodb表没有定义主键,每行还会增加一个6字节的rowid列。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
mysql>
create
table
yb1(
-> t1
varchar
(10),
-> t2
varchar
(10),
-> t3
char
(10),
-> t4
varchar
(10)
-> ) row_format=compact;
Query OK, 0
rows
affected (0.01 sec)
mysql>
insert
into
yb1
values
(
'a'
,
'bb'
,
'bb'
,
'ccc'
);
Query OK, 1 row affected (0.00 sec)
mysql>
insert
into
yb1
values
(
'd'
,
'ee'
,
'ee'
,
'fff'
);
Query OK, 1 row affected (0.00 sec)
mysql>
insert
into
yb1
values
(
'd'
,
NULL
,
NULL
,
'fff'
);
Query OK, 1 row affected (0.01 sec)
mysql>
select
*
from
yb1\G
*************************** 1. row ***************************
t1: a
t2: bb
t3: bb
t4: ccc
*************************** 2. row ***************************
t1: d
t2: ee
t3: ee
t4: fff
*************************** 3. row ***************************
t1: d
t2:
NULL
t3:
NULL
t4: fff
3
rows
in
set
(0.00 sec)
mysql>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# hexdump -C -v yb1.ibd > yb1.txt
然后分析:
0000c070 73 75 70 72 65 6d 75 6d 03 0a 02 01 00 00 00 10 |supremum........|
0000c080 00 2d 00 00 01 fa dd d5 00 00 00 00 39 ea a3 00 |.-..........9...|
0000c090 00 01 e8 01 10 61 62 62 62 62 20 20 20 20 20 20 |.....abbbb |
0000c0a0 20 20 63 63 63 03 0a 02 01 00 00 00 18 00 2b 00 | ccc.........+.|
0000c0b0 00 01 fa dd d6 00 00 00 00 39 eb a4 00 00 01 e9 |.........9......|
0000c0c0 01 10 64 65 65 65 65 20 20 20 20 20 20 20 20 66 |..deeee f|
0000c0d0 66 66 03 01 06 00 00 20 ff 96 00 00 01 fa dd d7 |ff..... ........|
0000c0e0 00 00 00 00 39 f0 a7 00 00 01 ea 01 10 64 66 66 |....9........dff|
0000c0f0 66 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |f...............|
0000c100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
0000c110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
0000c120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
第一行记录从0000c078开始:
03 0a 02 01
/* 变长字段长度列表,逆序的(03表示t4字段的值ccc的长度,0a表示t3字段的长度,02表示t2字段的值bb的长度,01表示t1字段的值a的长度)*/
00
/* NULL标志位,第一行没有NULL值 */
00 00 10 00 2d
/* record header,固定5字节 */
00 00 01 fa dd d5
/* rowid,innodb自动创建,6个字节 */
00 00 00 00 39 ea
/* 事务ID */
a3 00 00 01 e8 01 10
/* 回滚指针 */
61
/* 列1数据'a' */
62 62
/* 列2数据'bb' */
62 62 20 20 20 20 20 20 20 20
/* 列3数据'bb' (固定长度未完全使用时,使用0x20表示) */
63 63 63
/* 列4数据'ccc' */
第二行记录从0000c0a5开始:
03 0a 02 01
/* 变长字段长度列表,逆序的(03表示t4字段的值fff的长度,0a表示t3字段的长度,02表示t2字段的值ee的长度,01表示t1字段的值d的长度)*/
00
/* NULL标志位,第一行没有NULL值 */
00 00 18 00 2b
/* record header,固定5字节 */
00 00 01 fa dd d6
/* rowid,innodb自动创建,6个字节 */
00 00 00 00 39 eb
/* 事务ID */
a4 00 00 01 e9 01 10
/* 回滚指针 */
64
/* 列1数据'd' */
65 65
/* 列2数据'ee' */
65 65 20 20 20 20 20 20 20 20
/* 列3数据'ee' (固定长度未完全使用时,使用0x20表示) */
66 66 66
/* 列4数据'fff' */
record header的最后两个字节代表是下一个记录的偏移量,本例中是0x2b(即43)
第三行记录从0000c0d2开始:
03 01
/* 变长字段长度列表,逆序的(03表示t4字段的值fff的长度,01表示t1字段的值d的长度)*/
06
/* NULL标志位,第三行有NULL值。06换成二进制为00000110,表示第2,3列是null */
00 00 20 ff 96
/* record header,固定5字节 */
00 00 01 fa dd d7
/* rowid,innodb自动创建,6个字节 */
00 00 00 00 39 f0
/* 事务ID */
a7 00 00 01 ea 01 10
/* 回滚指针 */
64
/* 列1数据'd' */
64 64 64
/* 列4数据'fff' */
|
http://blog.jcole.us/2013/01/07/the-physical-structure-of-innodb-index-pages/