MySQL buffer pool里的三种链表和三种page
mysql buffer pool里的三種鏈表和三種page
buffer pool是通過三種list來管理的
1) free list
2) lru list
3) flush list
?
buffer pool中的最小單位是page,在innodb中定義三種page
1) free page :此page未被使用,此種類型page位于free鏈表中
2) clean page:此page被使用,對應數據文件中的一個頁面,但是頁面沒有被修改,此種類型page位于lru鏈表中
3) dirty page:此page被使用,對應數據文件中的一個頁面,但是頁面被修改過,此種類型page位于lru鏈表和flush鏈表中
?
buffer pool flush list的工作原理
?
dirty page如何存在flush鏈表中?
在flush list中存在的page只能是dirty page,flush list中存在的dirty page是按著oldest_modification時間排序的,當頁面訪問/修改都被封裝為一個mini-transaction,mini-transactin提交的時候,則mini-transaction涉及到的頁面就進入了flush鏈表中,oldest_modification的值越大,說明page越晚被修改過,就排在flush鏈表的頭部,oldest_modification的值越小,說明page越早被修改過,就排在flush鏈表的尾部,這樣當flush鏈表做flush動作時,從flush鏈表的尾部開始scan,寫出一定數量的dirty page到磁盤,推薦checkpoint點,使恢復的時間盡可能的短。除了flush鏈表本身的flush操作可以把dirty page從flush鏈表刪除外,lru鏈表的flush操作也會讓dirty page從flush鏈表刪除。
buffer pool lru list的工作原理
總的來說每當一個新頁面被讀取buffer pool之后,MySQL數據庫InnoDB存儲引擎都會判斷當前buffer pool的free page是否足夠,若不足,則嘗試flush LRU鏈表。
在MySQL 5.6.2之前,用戶線程在讀入一個page (buf_read_page)、新建一個page(buf_page_create)、預讀page(buf_read_ahead_linear) 等等操作時,都會在操作成功之后,調用buf_flush_free_margin函數,判斷當前buffer pool是否有足夠的free pages,若free pages不足,則進行LRU list flush,釋放出足夠的free pages,保證系統的可用性。
通過判斷當前buf pool中需要flush多少dirty pages,才能夠預留出足夠的可被替換的頁面(free pages or clean pages in LRU list tail)。
?
說明:
可用pages由以下兩部分組成:
1. buf pool free list中的所有page,都是可以立即使用的。
2. buf pool LRU list尾部(5+2*BUF_READ_AHEAD_AREA)所有的clean pages。
其中:BUF_READ_AHEAD_AREA為64,是一個linear read ahead讀取的大小,1 extent
?
由于buf_flush_free_margin函數是在用戶線程中調用執行的,若需要flush LRU list,那么對于用戶的響應時間有較大的影響。因此,在MySQL 5.6.2之后,InnoDB專門開辟了一個page cleaner線程,處理dirty page的flush動作(包括LRU list flush與flush list flush),降低page flush對于用戶的影響。
在MySQL 5.6.2前后的版本中,LRU list flush的不同之處在于是由用戶線程發起,還是有后臺page cleaner線程發起。但是,無論是用戶線程,還是后臺page cleaner線程,再決定需要進行LRU list flush之后,都會調用buf_flush_LRU函數進行真正的flush操作。
?
不同之處在于,MySQL 5.6.2之前,用戶線程調用的buf_flush_free_margin函數,在判斷是否真正需要進行LRU list flush時,將LRU list tail部分的clean pages也歸為可以被replace的pages,不需要flush。而在page cleaner線程中,每隔1s,無論如何都會進行一次LRU list flush調用,無論LRU list tail中的page是否clean。這也可以理解,用戶線程,需要盡量降低flush的概率,提高用戶響應;而后臺線程,盡量進行flush嘗試,釋放足夠的free pages,保證用戶線程不會堵塞。
?
Buffer Pool LRU/Flush List flush對比
1).LRU list flush,由用戶線程觸發(MySQL 5.6.2之前);而Flush list flush由MySQL數據庫InnoDB存儲引擎后臺srv_master線程處理。(在MySQL 5.6.2之后,都被遷移到page cleaner線程中)
?
2).LRU list flush,其目的是為了寫出LRU 鏈表尾部的dirty page,釋放足夠的free pages,當buf pool滿的時候,用戶可以立即獲得空閑頁面,而不需要長時間等待;Flush list flush,其目的是推進Checkpoint LSN,使得InnoDB系統崩潰之后能夠快速的恢復。
?
3).LRU list flush,其寫出的dirty page,需要移動到LRU鏈表的尾部(MySQL 5.6.2之前版本);或者是直接從LRU鏈表中刪除,移動到free list(MySQL 5.6.2之后版本)。Flush list flush,不需要移動page在LRU鏈表中的位置。
?
4).LRU list flush,由于可能是用戶線程發起,已經持有其他的page latch,因此在LRU list flush中,不允許等待持有新的page latch,導致latch死鎖;而Flush list flush由后臺線程發起,未持有任何其他page latch,因此可以在flush時等待page latch。
?
5).LRU list flush,每次flush的dirty pages數量較少,基本固定,只要釋放一定的free pages即可;Flush list flush,根據當前系統的更新繁忙程度,動態調整一次flush的dirty pages數量,量很大。
?
buffer pool free list工作原理
free鏈表里存放的是空閑頁面,初始化的時候申請一定數量的page,在使用的過程中,每次成功load頁面到內存后,都會判斷free page是否夠用,如果不夠用的話,就flush lru鏈表和flush鏈表來釋放free page,這就可以滿足其他進程在申請頁面,使系統可用。
?
總結
以上是生活随笔為你收集整理的MySQL buffer pool里的三种链表和三种page的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql语法之update
- 下一篇: linux cmake编译源码,linu