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