目录
使用工具py_innodb_page_info.py(详细见:py_innodb_page_info.py工具使用_爱我所爱0505的博客-CSDN博客)来分析表空间。
如下所示,t_activity_detail的空间共832页,其中B+树节点页有296页,空闲页有533页。而B+树当前高度是2层,最高层page level <0001>,属于非叶子节点;page level <0000>是叶子节点。
- [root@488c1daa7967 py_innodb_page_info]# python py_innodb_page_info.py -v /home/MySQL5.7/mysql-5.7.35/data/test_mysql/t_activity_detail.ibd
- page offset 00000000, page type
- page offset 00000001, page type
- page offset 00000002, page type
- page offset 00000003, page type
, page level <0001> - page offset 00000004, page type
, page level <0001> - page offset 00000005, page type
, page level <0001> - page offset 00000006, page type
, page level <0001> - page offset 00000007, page type
, page level <0001> - page offset 00000008, page type
, page level <0001> - page offset 00000009, page type
, page level <0001> - page offset 0000000a, page type
, page level <0001> - page offset 0000000b, page type
, page level <0000> - page offset 0000000c, page type
, page level <0000> - page offset 0000000d, page type
, page level <0000> - page offset 0000000e, page type
, page level <0000> - page offset 0000000f, page type
, page level <0000> - page offset 00000010, page type
, page level <0000> - page offset 00000011, page type
, page level <0000> - ......
- page offset 000000e3, page type
, page level <0000> - page offset 00000000, page type
- page offset 00000000, page type
- ......
- page offset 00000000, page type
- page offset 00000100, page type
, page level <0000> - page offset 00000101, page type
, page level <0000> - page offset 00000102, page type
, page level <0000> - ......
- page offset 00000146, page type
, page level <0000> - page offset 00000000, page type
- page offset 00000000, page type
- ......
- page offset 00000000, page type
- Total number of page: 832:
- Freshly Allocated Page: 533
- Insert Buffer Bitmap: 1
- File Space Header: 1
- B-tree Node: 296
- File Segment inode: 1
page offset 0000000b表示0000000b页在表空间的偏移量(页的位置),如下计算:11 * 16KB = 180224 = 0x2c000。所以通过FileViewPro软件打开t_activity_detail.ibd,找到0x0002c000,就是0000000b页的起始位置。
默认页的大小为16KB,则12 * 16KB = 196608 = 0x30000,那么0x0002c000 ~ 0x0002ffff就是0000000b页的起始位置、结束位置。通过hexdump命令查找该页的信息,如下所示。
hexdump -C -s 180224 -n 16384 t_activity_detail.ibd
其中:
-n length 只格式化输入文件的前length个字节
-C 输出规范的十六进制和ASCII码
-b 单字节八进制显示
-c 单字节字符显示
-d 双字节十进制显示
-o 双字节八进制显示
-x 双字节十六进制显示
-s 从偏移量开始输出
- [root@488c1daa7967 test_mysql]# hexdump -C -s 180224 -n 16384 t_activity_detail.ibd
- 0002c000 f9 fa eb 37 00 00 00 0b ff ff ff ff 00 00 00 0c |...7............|
- 0002c010 00 00 00 00 52 69 ef 94 45 bf 00 00 00 00 00 00 |....Ri..E.......|
- 0002c020 00 00 00 00 00 d9 00 06 3b 48 80 22 2a de 10 91 |........;H."*...|
- 0002c030 00 00 00 05 00 00 00 10 00 00 00 00 00 00 00 00 |................|
- 0002c040 00 00 00 00 00 00 00 00 01 47 00 00 00 00 00 00 |.........G......|
- 0002c050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 |................|
- 0002c060 02 00 3c 69 6e 66 69 6d 75 6d 00 01 00 0b 00 00 |..
- 0002c070 73 75 70 72 65 6d 75 6d 01 00 00 00 00 01 00 00 |supremum........|
- 0002c080 01 01 01 a9 81 01 01 01 18 00 01 09 40 03 07 30 |............@..0|
- 0002c090 f8 0b 9f ff ff 2b 05 fd 0b fc 00 00 10 02 8f 30 |.....+.........0|
- 0002c0a0 30 30 30 30 30 35 00 00 00 00 4e 98 dd 00 00 01 |000005....N.....|
- 0002c0b0 62 01 10 37 36 37 31 38 2f 31 39 e8 b5 9b e5 ad |b..76718/19.....|
- 0002c0c0 a3 e4 b8 ad e5 9b bd e5 a5 b3 e6 8e 92 e8 b6 85 |................|
- 0002c0d0 e7 ba a7 e8 81 94 e8 b5 9b 44 e7 bb 84 e7 ac ac |.........D......|
- 0002c0e0 31 33 e8 bd ae ef bc 9a e5 9b 9b e5 b7 9d 76 73 |13............vs|
- 0002c0f0 e6 b2 b3 e5 8c 97 80 00 00 00 99 a2 27 00 00 99 |............'...|
- 0002c100 a2 27 26 6a 36 35 31 38 39 36 31 33 36 31 80 00 |.'&j6518961361..|
- 0002c110 00 03 72 6f 6f 6d 32 30 31 39 30 31 31 37 32 30 |..room2019011720|
- 0002c120 33 31 32 37 31 31 5f 53 52 32 80 00 00 00 99 a2 |312711_SR2......|
- 0002c130 27 00 00 30 31 80 00 00 00 31 7b 22 68 69 67 68 |'..01....1{"high|
- 0002c140 52 65 73 6f 6c 75 74 69 6f 6e 48 22 3a 22 68 74 |ResolutionH":"ht|
- 0002c150 74 70 3a 2f 2f 77 61 70 78 2e 63 6d 76 69 64 65 |tp://wapx.cmvide|
- 0002c160 6f 2e 63 6e 3a 38 30 38 30 2f 70 75 62 6c 69 73 |o.cn:8080/publis|
- 0002c170 68 2f 70 6f 6d 73 2f 69 6d 61 67 65 2f 37 35 30 |h/poms/image/750|
- 0002c180 30 2f 30 32 34 2f 30 35 33 2f 32 30 31 39 30 31 |0/024/053/201901|
- 0002c190 31 37 32 32 32 30 5f 30 30 32 5f 48 33 32 5f 31 |172220_002_H32_1|
- ......
- 0002c880 2b 05 fd 0b fc 04 00 28 02 a9 30 30 30 30 30 30 |+......(..000000|
- 0002c890 38 00 00 00 00 4e 98 dd 00 00 01 62 01 40 37 36 |8....N.....b.@76|
- ......
- 0002d330 00 48 02 89 30 30 30 30 30 31 32 00 00 00 00 4e |.H..0000012....N|
- 0002d340 98 dd 00 00 01 62 01 80 37 36 38 31 38 2f 31 39 |.....b..76818/19|
- ......
- 0002dd70 05 fd 0b fc 04 00 68 02 a8 30 30 30 30 30 31 36 |......h..0000016|
- 0002dd80 00 00 00 00 4e 98 dd 00 00 01 62 01 c0 37 36 39 |....N.....b..769|
- ......
- 0002e830 05 fd 0b fc 04 00 88 d8 37 30 30 30 30 30 32 30 |........70000020|
- 0002e840 00 00 00 00 4e 98 dd 00 00 01 62 02 00 37 37 30 |....N.....b..770|
- ......
- 0002ffe0 00 00 00 00 00 00 00 70 38 04 35 1a 00 70 28 39 |.......p8.5..p(9|
- 0002fff0 1d 79 13 34 08 8a 00 63 f9 fa eb 37 52 69 ef 94 |.y.4...c...7Ri..|
- 00030000
| 类型 | 名称 | 字节 | 示例起始 | 示例 | 说明 |
| File Header | FIL_PAGE_SPACE_ OR_CHKSUM | 4 | 0002c000 | f9 fa eb 37 | 代表页的checksum值 |
| FIL_PAGE_OFFSET | 4 | 0002c004 | 00 00 00 0b | 1. 该页在表空间的偏移量; 2. 对应page offset 0000000b。 | |
| FIL_PAGE_PREV | 4 | 0002c008 | ff ff ff ff | 1. 当前页的上一页的偏移量; 2. 0xffffffff,表示空,没有上页。 | |
| FIL_PAGE_NEXT | 4 | 0002c00c | 00 00 00 0c | 1. 当前页的下一页的偏移量; 2. 0x0000000c下一页的起始位置。 | |
| FIL_PAGE_LSN | 8 | 0002c010 | 00 00 00 00 52 69 ef 94 | 当前页被修改的日志序列号 | |
| FIL_PAGE_TYPE | 2 | 0002c018 | 45 bf | 1. 页的类型; 2. 0x45bf是B+树叶子节点 | |
| FIL_PAGE_FILE_ FLUSH_LSN | 8 | 0002c01a | 00 00 00 00 00 00 00 00 | 1. 表示该页更新到的日志序列号; 2. 仅在系统空间使用,其他使用是0。 | |
| FIL_PAGE_ARCH_ LOG_NO_ OR_SPACE_ID | 4 | 0002c022 | 00 00 00 d9 | 1. 该页属于哪个表空间; 2. 0xd9 = 217,查看information_schema .INNODB_SYS_DATAFILES中SPACE为217的表是: test_mysql/t_activity_detail | |
| Page Header | PAGE_N_DIR_ SLOTS | 2 | 0002c026 | 00 06 | 1. 页目录中的slots(槽)数量; 2. 每个槽,两个字节,查看Page Directory; 3. 0x0006 = 6,6 * 2 = 12个字节。 |
| PAGE_HEAP_TOP | 2 | 0002c028 | 3b 48 | 1. 堆中第一个记录的指针; 2. 记录以堆的形式存放。 | |
| PAGE_N_HEAP | 2 | 0002c02a | 80 22 | 1. 堆中的记录数,第15位表示行记录格式; 2. 包含Infimum、Supremum虚拟行 | |
| PAGE_FREE | 2 | 0002c02c | 2a de | 指向可重用空间的首指针 | |
| PAGE_GARBAGE | 2 | 0002c02e | 10 91 | 1. 已删除记录的字节数,即:行记录中的delete_flag=1时的记录大小的总数; 2. 0x1091 = 4241Byte | |
| PAGE_LAST_INSERT | 2 | 0002c030 | 00 00 | 最后插入行的位置(本行偏移量) | |
| PAGE_DIRECTION | 2 | 0002c032 | 00 05 | 1. 最后插入行的方向; 2. 0x05表示:PAGE_NO_DIRECTION | |
| PAGE_N_DIRECTION | 2 | 0002c034 | 00 00 | 一个方向连续插入的记录数 | |
| PAGE_N_RECS | 2 | 0002c036 | 00 10 | 1. 该页中的用户记录数; 2. 0x0010 = 16,不包括Infimum、Supremum。 | |
| PAGE_MAX_TRX_ID | 8 | 0002c038 | 00 00 00 00 00 00 00 00 | 1. 修改当前页的最大事务ID; 2. 仅在辅助索引中定义。 | |
| PAGE_LEVEL | 2 | 0002c040 | 00 00 | 1. 当前页在B+树索引的位置; 2. page level <0000>中0x00表示叶子节点,即:叶子节点总是第0层。 | |
| PAGE_INDEX_ID | 8 | 0002c042 | 00 00 00 00 00 00 01 47 | 1. 索引ID,当前页属于哪个索引; 2. 0x0147 = 327 | |
| PAGE_BTR_SEG_ LEAF | 10 | 0002c04a | 00 00 00 00 00 00 00 00 00 00 | 1. B+树数据页中的非叶子节点所在段的segment header; 2. 仅在B+树的Root页中定义。 | |
| PAGE_BTR_SEG_ TOP | 10 | 0002c054 | 00 00 00 00 00 00 00 00 00 00 | 1. B+树数据页所在段的segment header; 2. 仅在B+树的Root页中定义。 | |
| Infimum Records | ------ | 5 | 0002c05e | 01 00 02 00 3c | 1. 虚拟行Infimum的记录头; 2. 其中最后两字节:0x003c,是第一个用户行记录的相对位置,即:0x2c063 + 0x003c = 0x2c09f,则:0x2c0a0就是第一个用户行记录的起始位置。 |
| ------ | 8 | 0002c063 | 69 6e 66 69 6d 75 6d 00 | 1. 记录内容是:infimum,多了一个0x00字节; 2. 虚拟行只有一列,char(8),是字符的ascii码值的16进制,如:i 的ascii码是105 = 0x69; | |
| Supremum Records | ------ | 5 | 0002c06b | 01 00 0b 00 00 | 虚拟行Supremum的记录头 |
| ------ | 8 | 0002c070 | 73 75 70 72 65 6d 75 6d | 1. 记录内容是:supremum; 2. 虚拟行只有一列,char(8),是字符的ascii码值的16进制,如:s 的ascii码是115 = 0x73; | |
| Page Directory | ------ | 动态 | 0002fff7 (往前) | 00 70 28 39 1d 79 13 34 08 8a 00 63 | 1. 字节数:File Header中的PAGE_N_DIR_ SLOTS的数量:0x0006,每个槽2字节,所以: 6 * 2 = 12字节; 2. Page Directory是逆序存放的,即起始位置是0002fff7,往前数12字节。所以Page Directory的0002ffec(开始) ~ 0002fff7(结束)。 3. 0x0063(前两个字节)是Infimum行的位置,即:0x2c063; 4. 0x0070(最后两个字节)是supremum行的位置,即:0x2c070; |
| File Trailer | FIL_PAGE_END_ LSN | 8 | 0002fff8 | f9 fa eb 37 52 69 ef 94 | 1. 前4字节表示:本页的checksum值,与File Header中的FIL_PAGE_SPACE_OR_CHKSUM相同; 2. 后4字节表示:当前页被修改的日志序列号,与1. 中的FIL_PAGE_LSN相同; 3. 前后4字节的值,与File Header对应的值做checksum函数比较,若相同,则本页数据完整。 |
记录查找的过程是如下所示:
见第二章节所述,Page Directory的有:00 70 28 39 1d 79 13 34 08 8a 00 63,记录的相对位置是逆序存放的。0x63是infimum行的位置,即:0x2c063;0x0070是supremum行的位置,即:0x2c070。
其中0x088a、0x1334、0x1d79 、0x2839分别对应的位置是0x2c000 + 0x088a = 0x2c88a、0x2c000 + 0x1334 = 0x2d334、0x2c000 + 0x1d79 = 0x2dd79、0x2c000 + 0x2839 = 0x2e839。下表所示,页目录中slots对应的二进制。
| slot记录 | 相对位置 | 二进制 |
| 00 63 | 0x2c063 | 虚拟行infimum的位置 |
| 08 8a | 0x2c88a | 0002c880 2b 05 fd 0b fc 04 00 28 02 a9 30 30 30 30 30 30 |+......(..000000| |
| 13 34 | 0x2d334 | 0002d330 00 48 02 89 30 30 30 30 30 31 32 00 00 00 00 4e |.H..0000012....N| 0002d340 98 dd 00 00 01 62 01 80 37 36 38 31 38 2f 31 39 |.....b..76818/19| |
| 1d 79 | 0x2dd79 | 0002dd70 05 fd 0b fc 04 00 68 02 a8 30 30 30 30 30 31 36 |......h..0000016| 0002dd80 00 00 00 00 4e 98 dd 00 00 01 62 01 c0 37 36 39 |....N.....b..769| |
| 28 39 | 0x2e839 | 0002e830 05 fd 0b fc 04 00 88 d8 37 30 30 30 30 30 32 30 |........70000020| 0002e840 00 00 00 00 4e 98 dd 00 00 01 62 02 00 37 37 30 |....N.....b..770| |
| 00 70 | 0x2c070 | 虚拟行supremum的位置 |
每个slot里有多个行记录,记录按索引键值顺序存放,目的使用二叉查找法找到记录指针。所以根据页目录进行二叉查找记录。
linux之hexdump命令_12458355的技术博客_51CTO博客