14.5.2 Change Buffermysql
14.5.4 Log Buffer
3:首先來看BufferPoolsql
那數據在buffer裏是怎麼存儲的呢? 在看官方給的架構圖
先不細分析這個結構,大體看了下就是使用了LRU(least recently used 這個你們都很熟悉吧.不熟悉自行補充)算法. 而且把整個列表分了new和old兩部分. 還有一點就是列表裏每一項到底緩存數據的維度是什麼?因此下面將分3個部分介紹 1:buffer pool 緩存的數據維度是什麼? 2:爲何LRU算法還有new和old部分,爲何會這樣涉及? 3:實戰看下buffer pool相關的部分
1:buffer pool 緩存的數據維度是什麼?
When room is needed to add a new page to the buffer pool, the least recently used page is evicted and a new page is added to the middle of the list. 從官方這句話,咱們能夠得知每一項都是一頁數據 . 這個後期寫mysql索引文章的時候,會詳細分析爲何會是頁數據爲單位.
2:爲何LRU算法還有new和old部分,爲何會這樣設計?數據庫
其實你們想一想只有LRU算法的缺點就知道了. 看下圖
就是隨着新的數據頁進來,列表中的數據會被大量置換出去. 沒有達到緩存的目的. 其實官方也介紹了哪些狀況下會出現這種狀況[見下圖].
說白了,全表掃描,什麼mysqldump操做,select語句沒有where條件,都會把大量數據放進buffer bool,即時這些數據並非熱點數據, 但同時還會把熱點數據給排擠出去.
那增長了new和old部分,當出現上面操做,又是怎樣保護熱點數據呢?
可從上圖看出,新讀入的數據都放在old列表,而且不會替換掉new列表中的熱點數據. 那問題來了,何時old列表中數據會進入new列表呢?
實際上是進入buffer pool的數據,能被真正讀取到, 並停留必定時間窗口,纔會進入new列表 [有點像jvm內存分代,多大年齡能夠進入老年代].緩存
其實真實的狀況是: 首先mysql會預讀數據 [局部性原理,你們能夠自行了解] 另外加上上面說的全表掃描 mysqldump等. 這兩種狀況, 使進入的buffer pool中的數據並不必定被讀到, 因此不能直接把熱點數據給置換掉,才弄出來new列表和old列表,而且old列表的數據被訪問到,且經歷過T時間[時間窗口] 纔會進入new列表.服務器
3:實戰看下buffer pool相關的部分數據結構
窗口執行 show variables like '%buffer_pool%';
好像看不太懂,仍是從buffer pool的數據結構反推應該有哪些配置吧.架構
能夠看到有好多字段, 但有個POOL_ID=0 可見我本地就一個緩衝池.jvm
innodb_old_blocks_pct表明old列表的大小,範圍[5,95] 其餘本身到官網看吧.
innodb_old_blocks_time=1000 默認1s
綜合innodb_old_blocks_pct和innodb_old_blocks_time 有兩種狀況
若是業務中常常出現表掃描, 這時候就該把innodb_old_blocks_pct調小, 把innodb_old_blocks_time調大,避免不少預讀的數據進入緩衝區.
若是業務中沒有大量的表掃描. 這時候就該把innodb_old_blocks_pct調大,把innodb_old_blocks_time減少,讓熱點數據儘快進入new列表.減小磁盤io,提升性能.
INNODB_BUFFER_PAGE
INNODB_BUFFER_PAGE_LRU
先看第一張表:INNODB_BUFFER_PAGE 如今明白了 其實就是緩衝池中的全部的頁信息.
在來看第二張表INNODB_BUFFER_PAGE_LRU
實際上是LRU列表中的頁信息. 從這裏咱們能夠得出,BUFFER POOL 中不只僅只有一個LRU列表,還有其餘緩存信息.
HIT_RATE:表示命中率 不用說,越高越好.
PAGES_MADE_YONG: 這個是從old列表到new列表的數量。
另外咱們發現: FREE_BUFFERS: 7704
DATABASE_PAGES: 487 POOL_SIZE: 8191
7704+487=8191; 可見buffer_pool 中除來一個lru列表[目前是DATABASE_PAGES] 還有一個FREE_BUFFERS緩存. 其餘的緩存咱們下一次在一一分析.