INODE结构二进制页分析
前言
一起分析一下INODE的二进制文件
bash-3.2# python py_innodb_page_info.py ../lottery_match/league_map.ibd -v
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0001>
page offset 00000004, page type <B-tree Node>, page level <0000>
page offset 00000005, page type <B-tree Node>, page level <0000>
page offset 00000006, page type <B-tree Node>, page level <0000>
page offset 00000007, page type <B-tree Node>, page level <0000>
page offset 00000000, page type <Freshly Allocated Page>
Total number of page: 9:
Freshly Allocated Page: 1
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 5
File Segment inode: 1
二进制文件
之前有算过
第一页的起始范围是:0x0000~0x3fff,对应offset page 0-File Space Header
第二页的起始范围是:0x4000~0x7fff,对应offset page 1-Insert Buffer Bitmap
第三页的起始范围在:0x8000~0xbfff,对应offset page 2-File Segment inode
第四页的起始范围在:0xc000~0xffff,对应offset page 3-<B-tree Node>, page level <0001>
…
FILE_HEADER(38B)
00008000: 'BC B4 02 0C `00 00 00 02` 00 00 00 00 00 00 00 00
00008010: 00 00 00 00 23 D4 BF F6 00 03 00 00 00 00 00 00
00008020: 00 00 00 00 01 CB' FF FF FF FF 00 00 FF FF FF FF
FIL_PAGE_OFFSET(4B):值为00 00 00 02
List Node for Node Page List(12B)
00008020: 00 00 00 00 01 CB 'FF FF FF FF 00 00 FF FF FF FF
00008030: 00 00' 00 00 00 00 00 00 00 01 00 00 00 00 00 00
INODE Entry 01(192B)
算的时候真的要小心,不能眼花。一错全错!
00008030: 00 00 `00 00 00 00 00 00 00 01` `00 00 00 00` `00 00
00008040: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00` `00 00
00008050: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00` `00 00
00008060: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00` `05 D6
00008070: 69 D2` `00 00 00 03` FF FF FF FF FF FF FF FF FF FF
00008080: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008090: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000080a0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000080b0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000080c0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000080d0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000080e0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000080f0: FF FF' 00 00 00 00 00 00 00 02 00 00 00 00 00 00
3个Base代表:某个段的某个链表的头节点和尾节点
Segment ID(8B):0x01,新的段ID是以1开始的。NOT_FULL_N_USED(4B):在NOT_FULL链表中已经使用了多少个页面。
值为:00 00 00 00List Base Node For FREE List(16B):完全没有被使用并分配给该Segment的Extent链表。
值为:00 00 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00,指向的是默认。List Base Node For NOT_FULL List(16B):至少有一个Page分配给当前Segment的Extent链表,全部用完时,转移到FSEG_FULL(16B),全部释放时,则归还FSP_FREE。
值为:00 00 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00List Base Node For FULL List:分配给当前Segment且Page完全使用完的Extent链表。
值为:00 00 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00Magic Number(4B):标记这个INODE Entry是否已经被初始化,初始化的意思就是把各个字段的值都填进去了。
值为:05 D6 69 D2。如果这个数字是值的97937874,表明该INODE Entry已经初始化,否则没有被初始化Fragment Array Entry(4B):记录的是一个零散页面的页号。
值为:00 00 00 03。这个页号很熟悉,就是page offset 00000003, page type <B-tree Node>, page level <0001>
INODE Entry 02(192B)
000080f0: FF FF '`00 00 00 00 00 00 00 02` `00 00 00 00` `00 00
00008100: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00` `00 00
00008110: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00` `00 00
00008120: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00` `05 D6
00008130: 69 D2` `00 00 00 05` `00 00 00 06` `00 00 00 07` FF FF
00008140: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008150: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008160: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008170: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008180: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008190: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000081a0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000081b0: FF FF' 00 00 00 00 00 00 00 03 00 00 00 00 00 00
- 段ID是0x02
- 对应的
Fragment array page为00 00 00 0500 00 00 0600 00 00 07
INODE Entry 03(192B)
000081b0: FF FF '`00 00 00 00 00 00 00 03` `00 00 00 00` `00 00
000081c0: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00` `00 00
000081d0: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00` `00 00
000081e0: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00` `05 D6
000081f0: 69 D2` `00 00 00 04` FF FF FF FF FF FF FF FF FF FF
00008200: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008210: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008220: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008230: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008240: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008250: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008260: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008270: FF FF' 00 00 00 00 00 00 00 04 00 00 00 00 00 00
- 段ID是0x03
- 对应的
Fragment array page为00 00 00 04
INODE Entry 04(192B)
00008270: FF FF '00 00 00 00 00 00 00 04 00 00 00 00 00 00
00008280: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00 00 00
00008290: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00 00 00
000082a0: 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00 05 D6
000082b0: 69 D2 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000082c0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000082d0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000082e0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
000082f0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008300: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008310: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008320: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00008330: FF FF' 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 段ID是0x04
- 对应的
Fragment array page没有页号。
INode Entry小结
前面说过:一个索引两个段,该数据表有两个索引–id(primary key)和lottery_id(unique key)。那么理论上应该有4个段才对,也就对应4个INode Entry。从以上分析也验证确实是4个。
根据上面的INode Entry还可以知道:
段01指向的页号是03。索引页-树的层级是1
段02指向的页号是05,06,07。数据页-树的层级是0
段03指向的页号是04。数据页
段04没有指向页号
这里可以大胆的猜测:
页号03是id的非叶子节点-索引页,页号05、06、07是id的叶子节点-数据页
页号04是lottery_id的叶子节点-数据页,目前还没有非叶子节点。
之所以这么认为是因为id是主键–对应那句话索引即数据,数据即索引。自然占用的内存更多。而lottery_id只是唯一键,只需存储的值只有页号、id,lottery_id。
这里没有细说
List Base Node,后文继续。

本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu