一看就懂的:MySQL數據頁以及頁分裂機制

文章公號 首發!連載中~ 歡迎各位大佬關注, 回復:「抽獎」 還可參加抽📖活動

文末有二維碼

一、知識回顧

回顧一下之前和大家分享的知識點

看了前面的文章,想必你肯定了解了什麼是Buffer Pool、LRU-List、Free-List、Flush-List,你也知道了當MySQL增刪改查時,記憶體中發生了什麼,以及這幾個雙向鏈表是如何配合工作的。

通過閱讀上一篇文章你也一定了解了:你create出來的table其實是屬於一個表空間的,而所謂的表空間其實對應著一個真實存在於物理磁碟上的文件。

並且在前面的文章中,白日夢曾不止一次的提及到:InnoDB從磁碟中讀取數據的最小單位是數據頁。而你想得到的id = xxx的數據,就是這個數據頁眾多行中的一行。

下面我們就一起看下,究竟什麼是MySQL的數據頁、數據區等概念。

二、數據頁長啥樣?

數據頁長下面這樣:

三、什麼是數據區?

在MySQL的設定中,同一個表空間內的一組連續的數據頁為一個extent(區),默認區的大小為1MB,頁的大小為16KB。16*64=1024,也就是說一個區裡面會有64個連續的數據頁。連續的256個數據區為一組數據區。

於是我們可以畫出這張圖:

從直觀上看,其實不用納悶為啥MySQL按照這樣的方式組織存儲在磁碟上的數據。

這就好比你搞了個Java的封裝類描述一類東西,然後再相應的給它加上一些功能方法,或者用golang封裝struct去描述一類對象。最終的目的都是為了方便、管理、控制。

約定好了數據的組織方式,那MySQL的作用不就是:按照約定數據規則將數據文件中的數據載入進記憶體,然後展示給用戶看,以及提供其他能力嗎?

四、數據頁分裂問題

假設你現在已經有兩個數據頁了。並且你正在往第二個數據頁中寫數據。

關於B+Tree,你肯定知道B+Tree中的葉子結點之間是通過雙向鏈表關聯起來的。

在InnoDB索引的設定中,要求主鍵索引是遞增的,這樣在構建索引樹的時候才更加方便。你可以腦補一下。如果按1、2、3…遞增的順序給你這些數。是不是很方便的構建一棵樹。然後你可以自由自在的在這棵樹上玩二分查找。

那假設你自定義了主鍵索引,而且你自定義的這個主鍵索引並不一定是自增的。

那就有可能出現下面這種情況 如下圖:

假設上圖中的id就是你自定義的不會自增的主鍵

然後隨著你將數據寫入。就導致後一個數據頁中的所有行並不一定比前一個數據頁中的行的id大。

這時就會觸發頁分裂的邏輯。

頁分裂的目的就是保證:後一個數據頁中的所有行主鍵值比前一個數據頁中主鍵值大。

經過分裂調整,可以得到下面的這張圖。

參考:

//dev.mysql.com/doc/refman/5.7/en/glossary.html

關注送書!《Netty實戰》

文章公號 首發!連載中!關注微信公號回復:「抽獎」 還可參加抽📖活動

誠信第一,活動真實有效,抓緊上車,馬上開獎!


Tags: