MySQL怎麼緩解讀的壓力的?---buffer pool

快樂的提千萬發表於2021-11-06

每當我們想要緩解讀,一般會想到什麼?

預讀取,快取

快取

快取,其實就是將高頻訪問的資料放到記憶體裡面,減少讀盤的次數。

為了提高記憶體的利用率,MySQL還建立了快取池,也就是buffer pool,儲存最熱的資料頁和索引頁。

預讀取(read-ahead)

從Linux的檔案系統我們就知道,計算機的讀取是按頁來的。那麼,我們是不是可以將下一頁提前取出來,反正是一次磁碟IO。

LRU(Least recently used)

提到快取和預讀取,LRU是跑不了的,簡單地說,就是將池子裡面待的最久的記憶體淘汰掉,放入新的資料

  • 裡面是個連結串列結構,首部新增,尾部淘汰。
  • 訪問的時候,如果在池子裡,就移動到首部,如果不在,就放到首部並把尾部淘汰。

image.png

那麼,缺點有沒有?

預讀失效:你放了我不讀。不就浪費了記憶體麼。

優化

凡是要區別對待,就將他們隔離開來。

我們想要的就是真正讀取的資料快取起來,預讀的資料級別低一點,稍微快取一下就好了。

那麼,很簡單,把記憶體池分段,一段存真正讀的,一段存預讀的。

這就是新生代(new sublist)和老生代(old sublist),新的尾就是老的頭。

邏輯不變,但是可以配置長度,比如新的站70%,老的佔30%,老的由於比較短,就會更快淘汰。

那麼, 完美了麼?

快取池汙染:如果SQL需要掃描大量的行,則可能將所有資料替換出去,這樣就等於快取直接失效了。

優化2.0

凡是要防止區別對待的事務強行混合,就新增閾值,讓低一級的過不來。

將所有的資料都先丟到老的裡面,停留時間大於T,才能進入新生代,這樣老的就在不斷被重新整理,而真正需要的會逐漸進入新生代。

相關引數

  • 快取池大小
  • 老生代比例
  • 老生代停留時間

結語

  • 如果有不對的地方歡迎指正。
  • 如果有不理解的地方歡迎指出我來加栗子。
  • 如果感覺OK可以點贊讓更多人看到它。

相關文章