Ⅰ、緩沖池介紹
InnoDB的緩沖池(buffer pool)類似于oracle的sga,里面存放數據頁、索引頁、change buffer、ahi等內容。
每次讀寫數據都需要通過buffer pool,當buffer pool中沒有用戶所需要的數據時則去硬盤中獲取。
?
通過緩沖池操作數據流程
innodb_buffer_pool_size參數控制緩沖池的總容量,5.7開始的版本可以在線動態調整該參數,一般來說,越大性能越好,如果所有熱數據都能緩存到緩沖池中,那樣性能是非??捎^的。
Ⅱ、緩沖池的性能問題
2.1 性能線性擴展
假設一臺服務器72core,ht超線程后,144個邏輯core,壓測時按道理144個core都應該跑滿,如果跑不滿就說明并發有瓶頸,加的core用不上,性能上不去。
5.1之前的版本常常被吐槽這個問題,現在已經不存在這個問題。
1G空間中有65536個頁,對這些頁進行管理,每次操作都要對緩沖池加鎖(latch,不是數據庫的lock),如果緩沖池太大了就會產生瓶頸。
qps達到1w,每秒鐘至少要獲取1w次latch,這里只看緩沖池的latch,忽略latch的釋放和喚醒,開銷非常大。
如何提升緩沖池性能
調整innodb_buffer_pool_instances參數,設置為cpu的數量。
假設開始這個值是1,現調整為4,原來1個緩沖池管理65536個頁,現在4個緩沖池,每個緩沖池管理16384個頁,拆成4個分片,將熱點打散,latch變少了,并發性能提升了。
這是非常常見的內核層對并發調優的手段,經測試,不調整與調整后性能相差30%。
注意:
設置多個緩沖池的時候,必須滿足每個池子大于1G才生效。
Ⅲ、緩沖池的管理
3.1 緩沖池的組成
?緩沖池核心組成
緩沖池中的熱點是以頁為單位來管理,并不是三種List加起來等于總的bp大小,而是Free List + LRU List(Flush List包含在LRU list中)。
Free List放空白的page,MySQL剛啟動時,緩沖池中有一個個16K的空白的頁,這些頁存放在(鏈表串聯)在Free List中。
LRU List包括LRU和unzip_LRU,當讀取一個數據頁的時候,就從Free List中取出一個頁,存入數據,并將該頁放入LRU List中。
當Free List給一個頁給LRU List時,這個過程中需要一個并發控制,也就是之前說的latch。假設現在有兩個線程都讀到磁盤上這個頁,則都需要問Free List來申請空閑頁,誰先來先給誰,latch就是對這三個List進行并發控制訪問的。
Flush List組織臟頁(被修改但未刷入磁盤的數據頁),根據每個臟頁的oldest_lsn進行排序。假設被讀到的頁,馬上被更新,這個頁就叫臟頁,會被放入到Flush List列表中,但只是放了一個指針(page Number),而不是實際的頁