Mysql--InnoDB數(shù)據(jù)頁結(jié)構(gòu)

Mysql--InnoDB數(shù)據(jù)頁結(jié)構(gòu)

  • 1.頁是innodb管理存儲(chǔ)空間的基本單位
  • 2.一般大小是16kb
  • 3.不同的頁存儲(chǔ)不同的數(shù)據(jù)類型,比如存放表空間頭部信息的頁,存放insertBuffer信息的頁面,存放INODE的頁,存放undo日志信息或者索引頁(數(shù)據(jù)頁)

數(shù)據(jù)頁(索引頁)

數(shù)據(jù)頁結(jié)構(gòu)如下

  • 1.File Header:文件頭部,頁的一些通用信息
  • 2.page Header:頁面頭部,數(shù)據(jù)頁專有的一些信息
  • 3.infimum+supremum:行記錄最小值和最大值,兩個(gè)虛擬的行記錄
  • 4.user recorders:實(shí)際存儲(chǔ)的行記錄內(nèi)容
  • 5.free space:頁中尚未使用的空間
  • 6.Page Directory:頁中的某些記錄的相對(duì)位置
  • 7.File Tailer:校驗(yàn)頁是否完整

記錄在頁中的存儲(chǔ)

  • 1.當(dāng)一個(gè)記錄需要插入頁的時(shí)候,會(huì)從free space劃分空間到user recorders
  • 2.Free Space部分的空間全部被User Records部分替代掉之后,也就意味著這個(gè)頁使用完了,如果還有新的記錄插入的話,就需要去申請(qǐng)新的頁了。

記錄頭信息的秘密

  • 1.預(yù)留位1 沒有使用
  • 2.預(yù)留位2 沒有使用
  • 3.delete_mask 標(biāo)記該記錄是否被刪除
  • 4.min_rec_mask B+樹的每層非葉子節(jié)點(diǎn)中的最小記錄都會(huì)添加該標(biāo)記--``
  • 5.n_owned 表示當(dāng)前記錄擁有的記錄數(shù),一般是每個(gè)頁中的每個(gè)槽中最大值標(biāo)識(shí)這個(gè)槽有幾個(gè)記錄。
  • 6.heap_no 表示當(dāng)前記錄在記錄堆的位置信息
  • 7.record_type 表示當(dāng)前記錄的類型,0表示普通記錄,1表示B+樹非葉節(jié)點(diǎn)記錄,2表示最小記錄,3表示最大記錄
  • 8.next_record 表示下一條記錄的相對(duì)位置

delete_mask

  • 1.這個(gè)屬性標(biāo)記著當(dāng)前記錄是否被刪除,占用1個(gè)二進(jìn)制位,值為0的時(shí)候代表記錄并沒有被刪除,為1的時(shí)候代表記錄被刪除掉了
  • 2.被刪除的記錄還在頁中,所有被刪除掉的記錄都會(huì)組成一個(gè)所謂的垃圾鏈表---可重用空間
  • 3.如果有新記錄插入到表中的話,可能把這些被刪除的記錄占用的存儲(chǔ)空間覆蓋掉。
  • 4.將這個(gè)delete_mask位設(shè)置為1和將被刪除的記錄加入到垃圾鏈表中其實(shí)是兩個(gè)階段

min_rec_mask

  • 1.B+樹的每層非葉子節(jié)點(diǎn)中的最小記錄都會(huì)添加該標(biāo)記(即目錄頁)
  • 2.如果不是非葉子節(jié)點(diǎn)的最小記錄則值為0,是的話就是1。

n_owned

  • 1.一個(gè)數(shù)據(jù)頁被分為多個(gè)組
  • 2.每個(gè)組中的最后一條記錄的n_owned標(biāo)記該組有多少個(gè)記錄
  • 3.其他的記錄該屬性為0

heap_no

  • 1.某頁中的記錄在該頁中的位置
  • 2.用戶記錄從2開始,0和1給最大和最小的2個(gè)虛擬記錄。
  • 3.記錄大小的比較是比較主鍵的大小

偽記錄的組成

  • 1.記錄頭信息和固定的字節(jié)
  • 2.字節(jié)代表的意思是,最小記錄就是inifimum,最大記錄就是supremum

record_type

  • 1.這個(gè)屬性表示當(dāng)前記錄的類型
  • 2.0表示普通記錄,1表示B+樹非葉節(jié)點(diǎn)記錄,2表示最小記錄,3表示最大記錄

next_record

  • 1.從當(dāng)前記錄的真實(shí)數(shù)據(jù)到下一條記錄的真實(shí)數(shù)據(jù)的地址偏移量
  • 2.第一條記錄的next_record值為32,意味著從第一條記錄的真實(shí)數(shù)據(jù)的地址處向后找32個(gè)字節(jié)便是下一條記錄的真實(shí)數(shù)據(jù)
  • 3.下一條記錄指得并不是按照我們插入順序的下一條記錄,而是按照主鍵值由小到大的順序的下一條記錄
  • 4.Infimum記錄(也就是最小記錄) 的下一條記錄就是本頁中主鍵值最小的用戶記錄
  • 5.而本頁中主鍵值最大的用戶記錄的下一條記錄就是 Supremum記錄(也就是最大記錄)
  • 6.最大記錄的next_record的值為0,這也就是說最大記錄是沒有下一條記錄
  • 7.當(dāng)數(shù)據(jù)頁中存在多條被刪除掉的記錄時(shí),這些記錄的next_record屬性將會(huì)把這些被刪除掉的記錄組成一個(gè)垃圾鏈表,以備之后重用這部分存儲(chǔ)空間。

Page Directory(頁目錄)

頁目錄簡(jiǎn)單介紹

  • 1.將所有正常的記錄(包括最大和最小記錄,不包括標(biāo)記為已刪除的記錄)劃分為幾個(gè)組。
  • 2.每個(gè)組的最后一條記錄(也就是組內(nèi)最大的那條記錄)的頭信息中的n_owned屬性表示該記錄擁有多少條記錄,也就是該組內(nèi)共有幾條記錄。
  • 3.將每個(gè)組的最后一條記錄的地址偏移量單獨(dú)提取出來按順序存儲(chǔ)到靠近頁的尾部的地方,這個(gè)地方就是所謂的Page Directory
  • 4.頁面目錄中的這些地址偏移量被稱為槽(英文名:Slot),所以這個(gè)頁面目錄就是由槽組成的。
  • 5.一組對(duì)應(yīng)一個(gè)槽
  • 6.對(duì)于最小記錄所在的分組只能有 1 條記錄
  • 7.最大記錄所在的分組擁有的記錄條數(shù)只能在 1~8 條之間
  • 8.剩下的分組中記錄的條數(shù)范圍只能在是 4~8 條之間

頁目錄中涉及到的分組

  • 1.初始情況下一個(gè)數(shù)據(jù)頁里只有最小記錄和最大記錄兩條記錄,它們分屬于兩個(gè)分組。
  • 2.之后每插入一條記錄,都會(huì)從頁目錄中找到主鍵值比本記錄的主鍵值大并且差值最小的槽,然后把該槽對(duì)應(yīng)的記錄的n_owned值加1,表示本組內(nèi)又添加了一條記錄,直到該組中的記錄數(shù)等于8個(gè)
  • 3.在一個(gè)組中的記錄數(shù)等于8個(gè)后再插入一條記錄時(shí),會(huì)將組中的記錄拆分成兩個(gè)組,一個(gè)組中4條記錄,另一個(gè)5條記錄。這個(gè)過程會(huì)在頁目錄中新增一個(gè)槽來記錄這個(gè)新增分組中最大的那條記錄的偏移量。

數(shù)據(jù)頁中查找指定主鍵值的記錄的過程分為兩步

  • 1.通過二分法確定該記錄所在的槽,并找到該槽中主鍵值最小的那條記錄。
  • 2.通過記錄的next_record屬性遍歷該槽所在的組中的各個(gè)記錄。

Page Header(頁面頭部)

  • 1.記錄該頁包含多少條記錄(包括最小和最大記錄以及標(biāo)記為刪除的記錄)
  • 2.記錄第一條記錄的地址(是該頁第一條記錄)
  • 3.頁目錄中存儲(chǔ)了多少個(gè)slot
  • 4.還未使用的空間最小地址,也就是說從該地址之后就是Free Space(比如給了99這個(gè)地址,則該頁尾部到99都是空閑地址)
  • 5.第一個(gè)已經(jīng)標(biāo)記為刪除的記錄地址(各個(gè)已刪除的記錄通過next_record也會(huì)組成一個(gè)單鏈表,這個(gè)單鏈表中的記錄可以被重新利用)
  • 6.已刪除記錄占用的字節(jié)數(shù)
  • 7.最后插入記錄的位置
  • 8.最后一條記錄插入的方向(PAGE_DIRECTION)
  • 9.一個(gè)方向連續(xù)插入的記錄數(shù)量(PAGE_N_DIRECTION)
  • 10.該頁中記錄的數(shù)量(不包括最小和最大記錄以及被標(biāo)記為刪除的記錄)
  • 11.修改當(dāng)前頁的最大事務(wù)ID,該值僅在二級(jí)索引中定義
  • 12.當(dāng)前頁在B+樹中所處的層級(jí)
  • 13.索引ID,表示當(dāng)前頁屬于哪個(gè)索引
  • 14.B+樹葉子段的頭部信息,僅在B+樹的Root頁定義
  • 15.B+樹非葉子段的頭部信息,僅在B+樹的Root頁定義

方向是指什么意思

  • 假如新插入的一條記錄的主鍵值比上一條記錄的主鍵值大,我們說這條記錄的插入方向是右邊,反之則是左邊

PAGE_N_DIRECTION注意點(diǎn)

  • 假設(shè)連續(xù)幾次插入新記錄的方向都是一致的,InnoDB會(huì)把沿著同一個(gè)方向插入記錄的條數(shù)記下來,這個(gè)條數(shù)就用PAGE_N_DIRECTION這個(gè)狀態(tài)表示。當(dāng)然,如果最后一條記錄的插入方向改變了的話,這個(gè)狀態(tài)的值會(huì)被清零重新統(tǒng)計(jì)

File Header(文件頭部)

  • 1.Page Header是專門針對(duì)數(shù)據(jù)頁記錄的各種狀態(tài)信息,而File Header則是對(duì)所有類型的數(shù)據(jù)頁都適用。
  • 2.頁的校驗(yàn)和(checksum值)
  • 3.頁號(hào)
  • 4.上一個(gè)頁的頁號(hào)
  • 5.下一個(gè)頁的頁號(hào)
  • 6.頁面被最后修改時(shí)對(duì)應(yīng)的日志序列位置(英文名是:Log Sequence Number)
  • 7.該頁的類型
  • 8.僅在系統(tǒng)表空間的一個(gè)頁中定義,代表文件至少被刷新到了對(duì)應(yīng)的LSN值
  • 9.頁屬于哪個(gè)表空間

File Trailer

  • 1.為了檢測(cè)一個(gè)頁是否完整(也就是在同步的時(shí)候有沒有發(fā)生只同步一半的尷尬情況)
  • 2.前4個(gè)字節(jié)代表頁的校驗(yàn)和
  • 3.后4個(gè)字節(jié)代表頁面被最后修改時(shí)對(duì)應(yīng)的日志序列位置(LSN)
  • 4.File Trailer與File Header類似,都是所有類型的頁通用的。

前4個(gè)字節(jié)代表頁的校驗(yàn)和

  • 1.每當(dāng)一個(gè)頁面在內(nèi)存中修改了,在同步之前就要把它的校驗(yàn)和算出來
  • 2.因?yàn)镕ile Header在頁面的前邊,所以校驗(yàn)和會(huì)被首先同步到磁盤,當(dāng)完全寫完時(shí)校驗(yàn)和也會(huì)被寫到頁的尾部
  • 3.如果完全同步成功,則頁的首部和尾部的校驗(yàn)和應(yīng)該是一致的
  • 4.如果寫了一半兒斷電了,那么在File Header中的校驗(yàn)和就代表著已經(jīng)修改過的頁,而在File Trialer中的校驗(yàn)和代表著原先的頁,二者不同則意味著同步中間出了錯(cuò)。

各個(gè)數(shù)據(jù)頁可以組成一個(gè)雙向鏈表,而每個(gè)數(shù)據(jù)頁中的記錄會(huì)按照主鍵值從小到大的順序組成一個(gè)單向鏈表,每個(gè)數(shù)據(jù)頁都會(huì)為存儲(chǔ)在它里邊兒的記錄生成一個(gè)頁目錄,在通過主鍵查找某條記錄的時(shí)候可以在頁目錄中使用二分法快速定位到對(duì)應(yīng)的槽,然后再遍歷該槽對(duì)應(yīng)分組中的記錄即可快速找到指定的記錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容