mysql 物理存儲 數據頁

MySQL Innodb 數據頁結構分析

頁(Page)是 Innodb 存儲引擎用於管理數據的最小磁盤單位。常見的頁類型有數據頁、Undo 頁、系統頁、事務數據頁等,本文主要分析的是數據頁。默認的頁大小爲 16KB,每個頁中至少存儲有 2 條或以上的行記錄,本文主要分析的是頁與行記錄的數據結構,有關索引和 B-tree 的部分在後續文章中介紹。

下圖是 Innodb 邏輯存儲結構圖,從上往下依次爲:Tablespace、Segment、Extent、Page 以及 Row。本文關注的重點是 Page 和 Row 的數據結構。

img

Page 結構

上圖爲 Page 數據結構,File Header 字段用於記錄 Page 的頭信息,其中比較重要的是 FIL_PAGE_PREV 和 FIL_PAGE_NEXT 字段,通過這兩個字段,我們可以找到該頁的上一頁和下一頁,實際上所有頁通過兩個字段可以形成一條雙向鏈表。Page Header 字段用於記錄 Page 的狀態信息。接下來的 Infimum 和 Supremum 是兩個僞行記錄,Infimum(下確界)記錄比該頁中任何主鍵值都要小的值,Supremum (上確界)記錄比該頁中任何主鍵值都要大的值,這個僞記錄分別構成了頁中記錄的邊界。

img

User Records 中存放的是實際的數據行記錄,具體的行記錄結構將在本文的第二節中詳細介紹。Free Space 中存放的是空閒空間,被刪除的行記錄會被記錄成空閒空間。Page Directory 記錄着與二叉查找相關的信息。File Trailer 存儲用於檢測數據完整性的校驗和等數據。

行記錄

Innodb 存儲引擎提供了兩種格式的行記錄:Compact 和 Redundant。

Compact 行記錄

img

變長字段長度列表:逆序記錄每一個列的長度,如果列的長度小於 255 字節,則使用一個字節,否則使用 2 個字節。該字段的實際長度取決於列數和每一列的長度,因此是變長的。

NULL 標誌位:一個字節,表示該行是否有 NULL 值(此處有疑問,8位,最多隻能表示 8 列?)

記錄頭信息:五個字節,其中 next_record 記錄了下一條記錄的相對位置,一個頁中的所有記錄使用這個字段形成了一條單鏈表。

列數據部分:除了記錄每一列對應的數據外,還有隱藏列,它們分別是 Transaction ID、Roll Pointer 以及 row_id(當沒有指定主鍵)。

注意:此處需要注意固定長度 CHAR 數據類型和變長 VCHAR 數據類型在 Compact 記錄下爲 NULL 時不佔用任何存儲空間。

Redundant 行記錄

字段長度偏移列表:與 Compact 中的變長字段長度列表相同的是它們都是按照列的逆序順序設置值的,不同的是字段長度偏移列表記錄的是偏移量,每一次都需要加上上一次的偏移,同時對於 CHAR 的 NULL 值,會直接按照最大空間記錄,而對於 VCHAR 的 NULL 值不佔用任何存儲空間。

注意:此處需要注意 VCHAR 類型和 CHAR 類型在建表時傳入的參數是字符長度而不是字節長度,實際的字節長度需要跟編碼方式相關聯,例如 UTF-8 一箇中文字符需要 3 字節來表示,這樣 CHAR(10) 以 UTF-8 來表示的話,它的字節長度在 10 - 30 之間。

行溢出

我們知道數據頁的大小是 16KB,Innodb 存儲引擎保證了每一頁至少有兩條記錄,如果一頁當中的記錄過大,會截取前 768 個字節存入頁中,其餘的放入 BLOB Page。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章