全表掃描這種情況的查詢,很多緩衝頁其實只會被訪問一次,但是它卻只因為被訪問了一次而進入到 young 區域,從而導致熱點資料被替換了
LRU 連結串列中 young 區域就是熱點資料,只要我們提高進入到 young 區域的門檻,就能有效地保證 young 區域裡的熱點資料不會被替換掉
MySQL 是這樣做的,進入到 young 區域條件增加了一個停留在 old 區域的時間判斷.
具體是這樣做的,在對某個處在 old 區域的快取頁進行第一次訪問時,就在它對應的控制塊中記錄下來這個訪問時間:
如果後續的訪問時間與第一次訪問的時間在某個時間間隔內,那麼該快取頁就不會被從 old 區域移動到 young 區域的頭部
如果後續的訪問時間與第一次訪問的時間不在某個時間間隔內,那麼該快取頁移動到 young 區域的頭部
如果後續的訪問時間與第一次訪問的時間不在某個時間間隔內,那麼該快取頁移動到 young 區域的頭部,這個間隔時間是由 innodb_old_blocks_time 控制的,預設是 1000 ms
也就說,只有同時滿足「被訪問」與「在 old 區域停留時間超過 1 秒」兩個條件,才會被插入到 young 區域頭部,這樣就解決了 Buffer Pool 汙染的問題
只要我們提高進入到 young 區域的門檻,就能有效地保證 young 區域裡的熱點資料不會被替換掉這句話該怎麼理解,為什麼設定 innodb_old_blocks_time 這個引數為 1 秒,能有效的避免因為全表掃描帶來的 Buffer Pool 汙染呢?
一個資料頁中含有多條記錄,因此全表掃描的情況下一個資料頁會被訪問多次,資料頁的第一次訪問和最後一次被訪問的時間間隔一般不會超過 1 秒,這樣它就不會被移動到 young 區域,導致 young 區域中的熱點資料淘汰掉,這樣就能避免因為全表掃描導致的 Buffer Pool 汙染了