深入理解MySQL——LRU、Free和Flush 链表
首先,緩沖池申請的內存空間一定是頁大小(默認16KB)的倍數,換句話說,雖然緩沖池是一塊很大的內存區域,然而在使用時是根據固定的頁大小進行管理的。如圖1-1所示∶
緩沖池有一個 free 鏈表,其中保存著未被使用的內存頁空間。當 free 鏈表中的頁都已分配完畢,當再要申請空間時,則需要根據LRU(Latest Recent Used 最近最少使用)算法淘汰已經使用的頁。
通常來說,數據庫中的緩沖池都是通過 LRU(Latest Recent Used 最近最少使用)算法來進行管理的。即最頻繁使用的頁在 LRU鏈表的前端,而最少使用的頁在 LRU鏈表的尾端。當緩沖池不能存放新讀取到的頁時,將首先從LRU 鏈表中釋放尾端的頁。
在InnoDB存儲引擎中,其同樣使用 LRU 算法對緩沖池進行管理。稍有不同的是 InnoDB存儲引擎對傳統的LRU算法做了一些優化。在InnoDB的存儲引擎中,LRU鏈表中還加入了midpoint 位置,新讀取到的頁,雖然是最新訪問的頁,但并不是直接放入到LRU 鏈表的首部,而是放入到LRU鏈表的 midpoint 位置。這個算法在 InnoDB存儲引擎下稱為 midpoint insertion strategy。默認配置下,該位置在 LRU鏈表長度的 3/8處,如圖1-2所示。
那為什么不采用樸素的 LRU 算法,直接將讀取的頁放入到LRU鏈表的首部呢?這是因為若直接將讀取到的頁放入到LRU的首部,那么某些 SOL 操作可能會使得緩沖池中的頁從LRU 鏈表中被刷新出,從而影響緩沖池的效率。常見的這類操作為索引或者數據的掃描操作。這類操作需要訪問表中的許多頁,甚至是全部的頁,而這些頁通常來說僅在這次查詢操作中需要,并不是活躍的熱點數據。如果頁被放入 LRU 鏈表的首部,那么非常可能將所需要的熱點數據頁從LRU鏈表中移除,而當下一次需要讀取該頁時,InnoDB存儲引擎需要再次訪問磁盤,從而導致數據庫性能的下降。
此外還需要特別注意的是,有些使用的頁并不存放在 LRU 鏈表中,例如自適應哈希,鎖信息。它們雖然同樣通過 free 鏈表申請空間,但是當申請完畢時,其并不放入LRU鏈表。所以在輸出的狀態中可以類似如下的內容∶
這里LRUlength+Flush list length并不等于Buffer Pool size,還少了505個頁。原因就在于緩沖池中的部分空間分配給了其他對象,在上述的例子中是由于自適應哈希索引的關系∶
node heap has 505 buffer(s)顯示了自適應哈希索引占用了505個緩沖池中的頁,可以看到在這里例子中,緩沖池中的頁分配給了自適應哈希索引、free 鏈表與LRU鏈表中的頁。
緩沖池中的頁不僅需要被讀取,還需要進行修改操作。修改的頁肯定發生在 LRU鏈表中,當LRU鏈表中的頁被修改后,則稱該頁為臟頁(dirty page),即緩沖池中的頁和磁盤上的頁數據產生了不一致。這時數據庫會通過 checkpoint 機制將臟頁刷新回磁盤。而 flush 鏈表中的頁即為臟頁。需要注意的是,臟頁既存在于LRU鏈表中,也存在于flush鏈表中。LRU鏈表用于管理緩沖池中頁的可用性,flush 鏈表則用干管理將頁刷新回磁盤,兩者互不影響。圖1-3顯示了 free 鏈表、LRU鏈表、flush 鏈表之間的關系∶
總結
以上是生活随笔為你收集整理的深入理解MySQL——LRU、Free和Flush 链表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 超大文本文件编辑器
- 下一篇: postgresql|数据库|插件学习(