MySQL 源碼學習(五)——Page和BTree

      網友投稿 939 2025-04-02

      InnoDB通過BTree實現索引,Page(這里主要指Index Page,以下類似)包含了所有數據和索引的信息。原因是:Page為了讓BTree索引更加高效,對Page的結構進行針對性的設計,使得Page被加載到內存中后,可以基于Page中的信息快速地構建出BTree,同時盡可能地減少額外的內存占用,提升BTree的修改、重構的性能。本文將通過Page的結構,來看InnoDB是如何做到這些的。

      Page的主要結構

      Page具有四個主要結構:File Header,Page Header, Page Body和Page Trailer。

      其中File Header,Page Header和Page Trailer是定長,分別占38,56和8個字節。

      而Page Body是變長的,主要存儲具體的數據。下面再分別說明每個部分的具體結構。

      File Header

      源代碼中,File Header可以在fil0file.h文件中找到:

      圖1 File Header定義

      這里主要關注FIL_PAGE_PREV,FIL_PAGE_NEXT及FIL_PAGE_TYPE三個字段。

      FIL_PAGE_TYPE

      FIL_PAGE_TYPE是PAGE的類型定義,我們知道Btr的數據都在leaf節點,非leaf節點只包含索引數據。PAGE中就一種類型,表示索引Page。從這里也就看出了,實際上整個Btr都是存儲在Page中的。

      FIL_PAGE_NEXT和PIL_PAGE_PREV

      BTree在同一層級,不同node間有一個橫向的指針,此兩者就是把同一個層級的不同Page連接起來,組成雙向鏈表的指針。

      Page Header

      Page Header可以在page0page.h文件中找到定義:

      圖2 Page Header的定義

      Page Header主要用于記錄Page的狀態信息,共56個字節,這里暫時不展開說明。

      Page Body

      Page Body包含了User Record,System Record,Free Space以及Page Dictionary四個部分。

      User Record就是存儲的實際數據,為InnoDB的行數據格式。

      System Record中包含了兩個特殊的Record:Infimum Record和Supremum Record。這兩個Record是用來表示User Record的邊界。Page Body中,User Record也是以鏈表的形式存儲,因此使用Infimum Record表示鏈表的頭,Supremum Record表示鏈表尾部。為什么要有這兩個特殊的Record呢。原因是我們在操作表記錄時,主鍵有可能是不連續的,也有可能在兩個主鍵中間插入一個擁有新主鍵的記錄。但是Page在物理上是連續的,因此只能通過鏈表來實現邏輯上的連續。當我們用index進行order by時,數據庫并不需要進行排序,而只需要遍歷鏈表即可,這也就是通過索引查詢高效的原因之一。如圖3所示,1~5是鏈表連接的順序,也是記錄的邏輯順序。

      圖3 User Record鏈表的邏輯順序

      Free Space

      Free Space是空閑的空間,當記錄被刪除后,User Record所占用的空間就會被放到Free Space中。

      Page Dictionary

      Page Dirctionary用于存放Page中Record的相對位置。這種相對位置并非是偏移量,而是類似于一個記錄的指針。同時并不是每個記錄都會有一個這樣的指針,而是擁有這樣指針的記錄,會使用一個額外的屬性:n_owned來記錄這條記錄后面跟隨了幾條記錄。這樣就可以在找到這條記錄之后,再次向后找到后面真正需要查找的記錄。

      需要Page Dictionary的目的是:通過Btree并不能直接查找到對應的Record(Btree 的Leaf節點并不是一條一條的Record),只能找到這個Record所對應的Page,然后再通過Page Dictinary進行二叉查找找到對應的目錄。

      MySQL 源碼學習(五)——Page和BTree

      Page Trailer

      Page的尾部,只有FIL_PAGE_END_LSN一個字段,8個字節,前4個字節是該頁的checksum,后4個字節是File Header中的FILE_PAGE_LSN。主要是用于檢測Page是否被完整的寫入了磁盤。

      從上面對Page對說明中,我們可以看出,BTree是隱含在Page結構中的數據結構。用一張圖來表示的話,可以表示為:

      圖4 Page視角的BTree

      RDS-MYSQL 云數據庫 MySQL RDS MySQL MySQL

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel小數點設置方法
      下一篇:JSP頁面和產品明細頁面的綁定關系在Hybris WCMS cockpit什么地方能夠找到
      相關文章
      亚洲av无码专区亚洲av不卡| 成人婷婷网色偷偷亚洲男人的天堂| 鲁死你资源站亚洲av| 亚洲国产精品综合一区在线| 亚洲国产成人私人影院| 亚洲国产精品无码久久久蜜芽 | 亚洲一区二区三区深夜天堂| 亚洲精品美女在线观看播放| 亚洲精品资源在线| 亚洲网站在线播放| 亚洲日产2021三区| 亚洲AV成人噜噜无码网站| 亚洲三级在线视频| 亚洲AV日韩综合一区尤物| 亚洲 暴爽 AV人人爽日日碰| 亚洲熟妇av午夜无码不卡| 亚洲精品久久无码av片俺去也 | 亚洲网址在线观看你懂的| 久久久久久亚洲Av无码精品专口 | 亚洲AV无码乱码精品国产| 亚洲人成影院在线观看| 亚洲一区二区高清| 亚洲夜夜欢A∨一区二区三区| 亚洲一区二区三区香蕉| 亚洲av永久无码精品漫画| 久久亚洲私人国产精品| 亚洲欧洲国产经精品香蕉网| 亚洲一卡2卡4卡5卡6卡在线99 | 亚洲av激情无码专区在线播放| 亚洲男人的天堂在线播放| 亚洲综合色丁香麻豆| 久久精品国产99国产精品亚洲| 亚洲熟妇久久精品| 精品韩国亚洲av无码不卡区| 亚洲国产小视频精品久久久三级 | 亚洲国产精品无码专区影院| 亚洲综合综合在线| 亚洲熟妇AV一区二区三区宅男| 亚洲AV蜜桃永久无码精品| 亚洲精品无码mv在线观看网站| 亚洲视频在线观看|