官方名字:索引頁
存儲過程
所以你知道了,User Records 和 Free Space 之間是此消彼長的關系
舉例
create table demo( c1 int, c2 int, c3 varchar(10000), primary key(c1) )charset=ascii row_format=compact
簡化下,因為變長字段長度列表,null值列表都沒什么用
所以存儲記錄為:
* delete_mask:標記是否刪除了
* heap_no:記錄的序號,序號為0的記錄是infimum,序號1為spuermum(這倆是mysql為我們自動提供的),所以我們自己的都是從2開始的,這個排序是通過主鍵的比較規則來的
* next_record:記錄下一條記錄的偏移量,下一條記錄指的是,按照主鍵值由小到大的下一天記錄。
假如刪除一條數據:
那么就等着下一條數據來,直接覆蓋就完事了
提問:為什么指針指的是中間位置,哈哈哈,這就是為什么左邊的可變長字段長度列表是逆序的原因了,從中間,往兩邊同時讀,剛好都是順的。自己畫圖理解下吧。
page_directory
將每個組的最大heap_no的記錄偏移地址存在page_directory,這樣查找的時候,就可以通過page_directory二分查找,然后再進入相應的組中找,美滋滋。
組的大小一般都是1-8個左右。
page header
數據頁中存儲的記錄的狀態信息,比如:存儲了多少條記錄,第一條記錄的地址是什么,有多少個槽
file header
有一個校驗和A
還有指向下一個頁面
存的都是跟頁面有關的信息
file trailer
校驗和B
假如現需要將數據頁寫入磁盤,寫到中途斷電了,那么校驗和A和校驗和B勢必不一樣,那么就說明出錯了,只寫了一半。
總結
- InnoDB為了不同的目的設計了不同類型的頁,我們把用於存放記錄的頁叫做數據頁
- 一個數據頁可以被大致分為7個部分,分別是:
- File Header:表示頁的一些通用信息,占固定的38字節
- Page Header:表示數據頁專有的一些信息,占固定的56個字節
- Infimum + Supremum:兩個虛擬的偽記錄,分別表示頁中的最小和最大記錄,占固定的26個字節
- User Records:真實存儲我們插入的記錄的部分,大小不固定
- Free Space:頁中尚未使用的部分,大小不確定
- Page Directory:頁中的某些記錄相對位置,也就是各個槽在頁面中的地址偏移量,大小不固定,插入的記錄越多,這個部分占用的空間越多
- File Trailer:用於檢驗頁是否完整的部分,占用固定的8個字節
- 每個記錄的頭信息中都有一個next_record屬性,從而使頁中的所有記錄串聯一個單鏈表
- InnoDB會為把頁中的記錄划分為若干個組,每個組的最后一個記錄的地址偏移量作為一個槽,存放在Page_Directory中,所以在一個頁中根據主鍵查找記錄是非常快的,分為兩步:
- 通過二分法確定槽
- 通過記錄的next_record屬性遍歷該槽所在的組中的各個記錄
- 每個數據頁的File Header 部分都有上一個和下一個頁的編號,所以所有的數據頁會組成一個雙鏈表
- 為保證從內存中同步到磁盤的頁的完整性,在頁的首部和尾部都會存儲頁中數據的校驗和和頁面最后修改時對應的LSN值,如果首部和尾部的校驗和和LSN值校驗不成功的話,就說名同步失敗了。