MySQL 執行原理【資料頁】

sayhe110發表於2019-09-09

文章根據《MySQL技術內幕:InnoDB儲存引擎(第二版)》、掘金小冊《MySQL是怎樣執行的:從根兒上理解MySQL》 兩本書得到的總結

文章參考 淘寶資料庫核心組月報
文章中的圖均截自《MySQL技術內幕:InnoDB儲存引擎(第二版)》

概述

之前在介紹表的那篇文章裡,簡單的介紹到了 資料頁 ,關於資料頁一點半點的文字根本介紹不清楚,所以單開一篇文章來介紹資料頁。

一切對資料庫的操作歸根到底就是對索引頁(Index page,文章中的資料頁都指的是索引頁)的操作,常見的頁型別有資料頁、undo頁、系統頁、事務資料頁、插入緩衝點陣圖頁等等,我們這篇文章只單單介紹資料頁。

頁結構

資料頁包括七個部分,資料頁檔案頭,資料頁頭,最大最小記錄,使用者記錄,空閒空間,資料目錄,資料頁尾部。資料頁簡單的分為兩大部分,一部分儲存資料記錄,按照記錄的大小通過記錄的指標連線起來,另一部分儲存資料頁的目錄。

1240

檔案頭(File Header)

File Header 主要用於儲存表空間相關資訊,組成部分如下:

1240
  • FIL_PAGE_SPACE_OR_CHKSUM:主要用於儲存資料頁的 checksum
  • FIL_PAGE_OFFSET:這個對應資料頁的 page number,每個表空間從 0 開始
  • FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID:現版本用於儲存 spaceid

資料頁頭(Page Header)

Page Header 主要用於儲存資料頁的元資訊,組成部分如下:

1240
  • PAGE_N_DIR_SLOTS:用於存放資料頁條目的個數,一個新建的初始資料頁就會有兩條記錄,分別指向最大最小記錄,在非空的資料頁中,第一條記錄永遠指向最小記錄,最後一條永遠指向最大記錄
  • PAGE_HEAP_TOP:指向資料頁中空閒空間的起始地址,由於有 PAGE_FREE 的記錄存在,小於 PAGE_HEAP_TOP 地址的也可以被重用
  • PAGE_N_HEAP:目前資料頁空間中的記錄數量,正常來說記錄著正常記錄和刪除記錄,所以說這個數不會減小隻會增加,一個新建的初始資料頁的 PAGE_N_HEAP 的預設值為 2 ,即為最大最小記錄
  • PAGE_FREE:記錄被刪除會進入這個刪除連結串列,如果有記錄插入,可以先從這個空間進行分配,若這個空間不夠用,則在 PAGE_HEAP_TOP 空間中分配
  • PAGE_DIRECTION:最後一個記錄插入的方向,從左插入從右插入,為了加速後續插入速度
  • PAGE_N_RECS:該頁中記錄的數量,不包括最大值最小值兩條記錄數

最大最小記錄(Infimum and superfimum records)

每個資料頁中有兩個虛擬行記錄用來限定記錄的邊界,infimum record 是資料頁上最小的記錄,所有使用者的記錄都大於它,superfimum record 是資料頁上最大的記錄,所有使用者的記錄都小於它,即他們兩為資料頁上的最大值最小值的邊界。

使用者記錄(User record)

使用者所有插入的資料記錄都被存放在此,每個資料記錄都有指向下一個記錄的指標,但是沒有指向上一個記錄的指標。記錄按照主鍵順序排序,即使用者可以從最小資料記錄開始遍歷,直到最大資料記錄,其中包括了所有正常資料記錄和被 delete-mark 的記錄,但是不會訪問到被標記刪除的記錄。

空閒空間(Free space)

在一條資料記錄被刪除後,該空間會被加入到空閒連結串列中。從 PAGE_HEAP_TOP 開始到最後一個資料目錄,這之間就是空閒空間,都被重置為 0,當使用者插入記錄的時候會首先從被刪除的記錄空間中查詢,若沒有合適的位置,則從空閒空間中分配,插入記錄後會遞增 PAGE_HEAP_TOP、PAGE_N_RECS 兩個值。

頁目錄(Page directory)

這裡強烈推薦看小冊的資料頁結構中頁目錄這一塊

頁目錄中存放了記錄的相對位置,這些記錄指標有時也被稱為槽(slots),並不是每個記錄都有槽,InnoDB儲存引擎中的槽是一個稀疏的目錄,這就代表了一個槽擁有多個記錄。由於在InnoDB儲存引擎中頁目錄是稀疏目錄,二叉查詢的結果只是一個粗略的結果,因此InnoDB儲存引擎必須通過 recorder header 中的 next_record 來繼續查詢相關記錄。

需要注意的是,B+樹索引並不能找到具體的一條記錄,能找到的只是該記錄的頁,資料庫把頁載入到記憶體,然後通過頁目錄進行二叉查詢,因為二叉查詢時間複雜度非常低,又在記憶體中進行查詢,所以這部分的查詢時間可以忽略不計。

檔案結尾資訊(File trailer)

這部分資訊處於資料頁的最後位置,只有 8 個位元組,為了檢測頁是否完整的重新整理至磁碟,其中只有一個 FIL_PAGE_END_LSN 部分,前 4 位元組代表該頁的 checksum 值,後 4 位元組和 file header 中的 FIL_PAGE_LSN 值相同。

相關文章