InnoDB 爲了避免同的目的而設計了不一樣類型的頁,咱們把用於存放記錄的頁叫作索引頁html
索引頁分爲如下部分:mysql
文件頭部各個類型的頁都有
包含如下部分:sql
名稱 | 大小 | 做用 |
---|---|---|
FIL_PAGE_SPACE_OR_CHKSUM | 4 | 頁的校驗和 (checksum) |
FIL_PAGE_OFFSET | 4 | 頁號 (每一個頁的都不一樣) |
FIL_PAGE_PREV | 4 | 上一個頁的頁號 |
FIL_PAGE_NEXT | 4 | 下一個頁的頁號 |
FIL_PAGE_LSN | 8 | 頁面被最後修改時對應的日誌序列位置 (Log Sequence Number) |
FIL_PAGE_TYPE | 2 | 該頁的類型 |
FIL_PAGE_FILE_FLUSH_LSN | 8 | 僅在系統表空間的一個頁中定義,表明文件至少被刷新到了對應的 LSN 值 |
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID | 4 | 頁屬於哪一個表空間 |
FIL_PAGE_PREV
和 FIL_PAGE_NEXT
表明上一頁和下一頁的頁碼,使得多個索引頁之間像雙向鏈表同樣鏈接起來設計
頁面頭部索引頁特有的,記錄了當前頁面的狀態信息
包含如下部分:日誌
名稱 | 大小 (byte) | 做用 |
---|---|---|
PAGE_N_DIR_SLOTS | 2 | 頁目錄中的槽數量 |
PAGE_HEAP_TOP | 2 | 還未使用的空間最小地址,也就是說從該地址以後就是 Free Space |
PAGE_N_HEAP | 2 | 本頁中的記錄的數量(包括最小和最大記錄以及標記爲刪除的記錄) |
PAGE_FREE | 2 | 第一個已經標記爲刪除的記錄地址(各個已刪除的記錄經過 next_record 也會組成一個單鏈表,這個單鏈表中的記錄能夠被從新利用) |
PAGE_GARBAGE | 2 | 已刪除記錄佔用的字節數 |
PAGE_LAST_INSERT | 2 | 最後插入記錄的位置 |
PAGE_DIRECTION | 2 | 記錄插入的方向 (新插入記錄的主鍵值比上一條記錄的主鍵值大,插入方向就是右邊,反之則是左邊) |
PAGE_N_DIRECTION | 2 | 一個方向連續插入的記錄數量 |
PAGE_N_RECS | 2 | 該頁中記錄的數量(不包括最小和最大記錄以及被標記爲刪除的記錄) |
PAGE_MAX_TRX_ID | 8 | 修改當前頁的最大事務 ID,該值僅在二級索引中定義 |
PAGE_LEVEL | 2 | 當前頁在 B+ 樹中所處的層級 |
PAGE_INDEX_ID | 8 | 索引 ID,表示當前頁屬於哪一個索引 |
PAGE_BTR_SEG_LEAF | 10 | B+ 樹葉子段的頭部信息,僅在 B+ 樹的 Root 頁定義 |
PAGE_BTR_SEG_TOP | 10 | B+ 樹非葉子段的頭部信息,僅在 B+ 樹的 Root 頁定義 |
兩個虛擬的行記錄,分別位於記錄鏈表的開頭和結尾code
用戶記錄是按照相應行格式存儲數據的地方
MySQL 行格式 <- 點擊查看htm
以 Compact 爲例:
藉助 next_record
,記錄之間像鏈表同樣鏈接起來,順序爲主鍵從小到大排序,第一個爲最小記錄,最後一條爲最大紀錄
next_record
指向的是下一紀錄真數據開始的地方,也就是下一紀錄 next_record
以後blog
當其中的一條記錄被刪除後,上一條記錄的 next_record
指向下一條紀錄,此記錄標記爲刪除,next_record
指向 0,當前組最後一條記錄 n_owned
更新排序
頁目錄在靠近頁尾部的地方,記錄着每組記錄中最後一條記錄的地址偏移量,每一個偏移量被放在槽 (Slot) 中索引
最小記錄所在的分組只能有 1 條記錄,最大記錄所在的分組擁有的記錄條數只能在 1~8 條之間,剩下的分組中記錄的條數範圍只能在是 4~8 條之間
n_owned
表示當前組中一共有幾條記錄
因爲頁目錄中記錄的主鍵是有順序的,因此能夠經過二分法進行查找
經過二分法在頁目錄找到對應的槽,再遍歷整個組中的記錄
用於確認內存同步到磁盤是否完整
分爲兩部分:
當一個頁面在內存中修改以後,在同步以前須要先計算出校驗和
File Header 在頁面的前面,因此校驗和會先進行同步,File Trialer 在最後進行同步,若是兩次校驗和不一樣說明數據改變了
各個索引頁能夠按照頁中最小主鍵值從小到大組成一個雙向鏈表,每一個索引頁中的記錄又會按照主鍵值從小到大組成一個單鏈表