INODE結構二進位制頁分析

so_easy發表於2020-09-19

前言

一起分析一下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 00
  • List Base Node For FREE List(16B):完全沒有被使用並分配給該SegmentExtent連結串列。
    值為: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分配給當前SegmentExtent連結串列,全部用完時,轉移到FSEG_FULL(16B),全部釋放時,則歸還FSP_FREE
    值為:00 00 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00
  • List Base Node For FULL List:分配給當前SegmentPage完全使用完的Extent連結串列。
    值為:00 00 00 00 FF FF FF FF 00 00 FF FF FF FF 00 00
  • Magic 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 page00 00 00 05 00 00 00 06 00 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 page00 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,後文繼續。

INODE二進位制分析

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章