InnoDB buffer pool詳解

在WAL機制中,InnoDB內存的一個作用是保存更新的結果,再配合redo log,避免了隨機寫盤。內存的數據頁是在Buffer Pool中管理的,在WAL裏Buffer Pool起到了加速更新的作用

由於有WAL機制,當事務提交的時候,磁盤上的數據頁是舊的,如果這時候馬上有一個查詢要來讀這個數據頁,不需要馬上把redo log應用到數據頁。因爲內存數據頁的結果是最新的,直接讀內存就可以了。Buffer Pool起到了加速查詢的作用

Buffer Pool對查詢的加速效果依賴於內存命中率。可以在show engine innodb status結果中,查看一個系統當前的BP命中率

InnoDB Buffer Pool的大小是由參數innodb_buffer_pool_size確定的,一般建議設置成可用物理內存的60%~80%

InnoDB內存管理用的是最近最少使用(LRU)算法並在此基礎上做了優化:
在這裏插入圖片描述
在InnoDB實現上,按照5:3的比例把整個LRU鏈表分成了young區域和old區域。圖中LRU_old指向的就是old區域的第一個位置,是整個鏈表的5/8處。也就是說,靠近鏈表頭部的5/8是young區域,靠近鏈表尾部的3/8是old區域

1.圖中狀態1,要訪問數據頁P3,由於P3在young區域,因此和優化前的LRU算法一樣,將其移到鏈表頭部,變成狀態2

2.之後要訪問一個新的不存在於當前鏈表的Pm,但是新插入的數據頁Px,是放在LRU_old處

3.處於old區域的數據頁,每次被訪問的時候都要做下面這個判斷:

  • 若這個數據頁在LRU鏈表中存在的時間超過了1秒,就把它移動到鏈表頭部
  • 如果這個數據頁在LRU鏈表中存在的時間短於1秒,位置保持不變。1秒這個時間,是由參數innodb_old_blocks_time控制的。默認值是1000,單位是毫秒

這個優化策略就是爲了處理類似全表掃描的操作量身定製的。以掃描200G的歷史數據表爲例:

1.掃描過程中,需要新插入的數據頁,都被放到old區域

2.一個數據頁裏面有多條記錄,這個數據頁會被多次訪問到,但由於是順序掃描,這個數據頁第一次被訪問和最後一次被訪問的時間間隔不會超過1秒,因此還是會被保留在old區域

3.再繼續掃描後續的數據,之前的這個數據頁之後也不會再被訪問到,於是始終沒有機會移到鏈表頭部,很快就會被淘汰出去

這個優化策略最大的收益就是在掃描這個大表的過程中,雖然也用到了Buffer Pool,但是對young區域完全沒有影響,從而保證了Buffer Pool響應正常業務的查詢命中率

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章