Page是Innodb存儲的最基本結構,也是Innodb磁盤管理的最小單位,與數據庫相關的所有內容都存儲在Page結構裏。Page分爲幾種類型:數據頁(B-Tree Node)
,Undo頁(Undo Log Page)
,系統頁(System Page)
,事務數據頁(Transaction System Page)
等;每個數據頁的大小爲16kb
,每個Page使用一個32位(一位表示的就是0或1)的int值來表示,正好對應Innodb最大64TB的存儲容量(16kb * 2^32=64tib)
一個Page的基本結構如下:
每個page都有通用的頭和尾,但是中部的內容根據page的類型不同而發生變化,頭部的數據如下:
page頭部保存了兩個指針,分別指向前一個Page和後一個Page,頭部還有Page的類型信息和用來唯一標識Page的編號。根據這個指針分佈可以想象到Page鏈接起來就是一個雙向鏈表
在Page的主體部分,主要關注數據和索引的存儲,他們都位於User Records
部分,User Records佔據Page的大部分空間,User Records由一條條的Record組成,每條記錄代表索引樹上的一個節點(非葉子節點和葉子節點);在一個單鏈表的內部,單鏈表的頭尾由兩條記錄來表示,字符串形式的「 Infimum」代表開頭,「Supremum」表示結尾;System Record 和 User Record是兩個平行的段;
Innodb中存在四種不同的Record,分別是
主鍵索引樹非葉子節點
主鍵索引樹葉子節點
輔助鍵索引樹非葉子節點
輔助鍵索引樹葉子節點
這四種節點Record格式上有差異,但是內部都存儲着Next指針指向下一個Record
User Record
User Record在Page內以單鏈表的形式存在,最初數據是按照插入的先後順序排列的,但是隨着新數據的插入和舊數據的刪除,數據物理順序發生改變,但是他們依然保持着邏輯上的先後順序
把User Record組織形式和若干Page組織起來,就得到了稍微完整的形式:
如何定位一個Record:
通過根節點開始遍歷一個索引的B+樹,通過各層非葉子節點達到底層的葉子節點的數據頁(Page),這個Page內部存放的都是葉子節點
在Page內部從「Infimum」節點開始遍歷單鏈表(遍歷一般會被優化),如果找到鍵則返回。如果遍歷到了「Supremum」,說明當前Page裏沒有合適的鍵,這時藉助Page頁內部的next page指針,跳轉到下一個page繼續從「Infmum」開始逐個查找
User Record內部的數據
User Record內部存儲了四種格式的數據:
主索引樹非葉子節點(綠色)
子節點存儲的主鍵裏最小的值,這時B+樹必須的,作用是在一個Page裏定位到具體的記錄的位置
最小的值所在的Page的編號,作用是定位到對應的Record所在的Page
主索引樹葉子節點(黃色)
主鍵,B+樹所必須的,也是數據行的一部分
除去主鍵以外的所有列,這時數據行的除去主鍵的其他所有列的集合
輔助索引樹非葉子節點(藍色)
子節點裏存儲的輔助鍵值裏的最小值,這時B+Tree必須的,作用是在一個Page裏定位到具體記錄的位置
輔助索引樹葉子節點(紅色)
輔助索引鍵值,是B+樹必須的
主鍵值,用來在主索引樹裏在做一次B+樹檢索來找到整條記錄
Page和B+樹之間並沒有一一對應的關係,Page只是作爲一個Record的保存容器,它存在的目的是便於對磁盤空間進行批量管理。