InnoDB資料頁的結構(FIL_PAGE_INDEX)
阿新 • • 發佈:2021-11-21
InnoDB存放著各種各樣的頁(page),這些page也分為各種不同的型別。如:FIL_PAGE_INDEX資料頁(帶有真實資料的)、FIL_PAGE_TYPE_ALLOCATED未分配頁、FIL_PAGE_TYPE_BLOG溢位頁……等十多個型別的頁,用於不同的用途。
補充:頁面管理的分類:
- 空閒頁:空閒頁
- 資料頁:乾淨頁
- 髒頁:跟磁碟資料不一致,需要生效
- File Header:檔案頭部,38位元組
- Page Header:頁面頭部,56位元組
- Infimum+Superman:頁面中的最小記錄+最大記錄。是虛擬記錄
- User Records:使用者記錄,真實資料
- Free Page:空閒空間,尚未使用的空間
- Page Directory:頁目錄
- File Trailer:檔案尾
- 所有未刪除的記錄將被劃分為若干個分組,包括偽記錄
- 每個組的最後一條記錄的n_owned屬性標記著當前分組的記錄數量
- 每個組的最後一條記錄在頁面中的地址偏移量提取出來,按順序放置到靠近頁尾的地方,這個地方就稱之為頁目錄(Page Directory),這些偏移量也稱為“槽”,每個槽佔2位元組,頁目錄就是由多個槽組成的。
- Infimum所在的分組,只能有Infimum記錄本身,即1條記錄
- Superman所在的分組記錄條數只能在1~8條之間,剩下其他分組條數範圍在4~8條之間
- 分組實現步驟:
- 初始狀態,一個page只有兩條記錄,兩個分組,兩個槽,分別記錄Infimum和Superman的地址偏移量
- 每插入一條記錄,都會從頁目錄中找到對應記錄的主鍵值比待插入記錄的主鍵值大且差值最小的槽(沒懂),然後把該槽對應的記錄的n_owned值+1,表示本組又添加了一條記錄,直至本組記錄數等於8
- 當一個組的記錄數等於8後,再插入一條記錄時,會講組中的記錄拆分成兩個組,其中一個組4條記錄,一個組5條記錄。拆分過程中會在頁目錄中新增一個槽,記錄這個新增分組中最大的那個記錄的偏移量
- 初始狀態下,設定low為0,hight為槽的總數量, 槽的數量也就是分組的數量。由於槽本身記錄著其分組最後一條記錄的偏移量,所以槽所對應的主鍵就是槽所在分組的最大主鍵。使用需要查詢的主鍵跟槽對比,修改low和hight兩個變數,最後對比出需要查詢的記錄具體在哪個槽。
- 知道某個槽(分組)中存放著我想要的記錄,則需要把這個槽從小到大逐個遍歷,我們拿到的槽的值是不可以用來遍歷的,因為槽的值只是當前分組的最大記錄,不能反向去遍歷。而頁目錄中的槽都是連續存放的,因此我們需要拿到上一個槽,獲取那條記錄的下一條記錄,也就是next_records值,然後遍歷所在分組的所有記錄,即可找到該主鍵對應的記錄。
- 預留1、2位:預留位,不用
- delete_flag:標記是否刪除。mysql中的做記錄刪除並沒有刪除記錄所在佔的空間,而是講該記錄置為1.如果刪除時連帶空間也刪除,則每次刪除一條記錄都需要重新排列其他記錄,造成效能消耗。因此使用該標記。並且所有被刪除的記錄就組成一個垃圾連結串列。記錄在該連結串列中的空間時可重用空間,後續新增資料時,又可能會覆蓋掉記錄,並佔用其空間。
- min_rec_flag:B+樹中的每層非葉子節點中的最小目錄項記錄會新增該標記
- n_owned:頁面內的記錄分成的組,每個組中有一個記錄的你n_owned值記錄著當前記錄組的條數,剩餘記錄該值均為0
- Heap_no:當前記錄在頁面堆中的相對位置。
- Record_type:記錄型別,普通記錄標記0;非葉節點的目錄標記1,Infimum標記2,Superman標記3
- Next_records:表示到下一條距離的相對位置。該屬性記錄當前記錄的真實資料到下一條記錄真實資料的距離。如果某條記錄該屬性位正數,則下一條記錄在該記錄的後面。例如:第一條記錄該屬性值為32,則下一條的真實資料地址在本條記錄的真實資料的地址往後+32位元組;如果某條記錄該屬性為負數-145,則下一條記錄的真實資料需要往前-145位元組。