InnoDB存儲引擎Change Buffer

簡介

變更緩沖區(qū)(原來的Insert Buffer)是一種特殊的數(shù)據(jù)結(jié)構(gòu),存儲位置在:

  • 緩沖池;
  • 磁盤的系統(tǒng)表空間;

大多數(shù)場景,輔助索引頁的訪問都會造成隨機(jī)的IO,相對順序IO來講效率非常差,對于輔助索引數(shù)據(jù)的INSERT,UPDATE或DELETE操作,對輔助索引操作來說,性能影響很大。需要去磁盤掃描輔助索引,數(shù)據(jù)量大的時候通常會有多次的隨機(jī)IO,才找到對應(yīng)輔助索引頁。因此Change Buffer正是來解決這個問題的。

Change Buffer工作原理

image.png

輔助索引數(shù)據(jù)的INSERT,UPDATE或DELETE操作,innoDB首先判斷輔助索引的頁是否在緩沖池中,如果在,則直接操作;如果不在,則先放到緩沖池的Change Buffer中,然后通過后臺線程按照一定的頻率和情況進(jìn)行Change Buffer和輔助索引頁的merge(合并)操作,通常能將多次的操作合并成一次操作(一個索引頁包含多個索引數(shù)據(jù)),這就大大提高了輔助索引數(shù)據(jù)操作的性能,可以通過innodb_change_buffer_max_size調(diào)整變更緩沖大小,默認(rèn)是25,最大只能設(shè)置為50,按照百分比取值。

Change Buffer的使用需要滿足以下兩個條件:

  • 索引是輔助索引;
  • 索引不是唯一的;

當(dāng)滿足以上兩個條件的時候,InnoDB會使用Change Buffer,這樣就能提高DML操作性能。當(dāng)然該機(jī)制也有一定的弊端:比如,大量的DML操作導(dǎo)致大量的Change Buffer沒有合并到輔助索引頁中,如果發(fā)生了宕機(jī),重啟恢復(fù)需要很長的時間。

考慮一個問題,為什么Change Buffer規(guī)定索引不是唯一的?

答案很明顯,Change Buffer設(shè)計的初衷就是為了減少磁盤隨機(jī)IO,如果是唯一索引,需要多一步索引唯一性校驗是需要訪問磁盤的,如果是這樣就會失去了意義。

Change Buffer數(shù)據(jù)結(jié)構(gòu)

Change Buffer的數(shù)據(jù)結(jié)構(gòu)實際上是一顆B+ Tree,由所有表進(jìn)行Change Buffer的非唯一輔助索引組成。

B+ Tree每個節(jié)點存儲內(nèi)容如下:

space marker offset metadata secondary index record
表空間id
占用4個字節(jié)
區(qū)分新老版本
占用1個字節(jié)
索引頁偏移量,即page_no
占用4個字節(jié)
元數(shù)據(jù)
占用4個字節(jié)
輔助索引記錄

metadata存儲內(nèi)容如下:

IBUF_REC_OFFECT_COUNT IBUF_REC_OFFECT_TYPE IBUF_REC_OFFECT_FLAGS
用來排序每個記錄進(jìn)入Change Buffer的順序
占用2個字節(jié)
對用緩存的操作類型
占用1個字節(jié)
表示行格式
占用1個字節(jié)

為了保證每次都能merge成功,還需要有一個特殊的頁來標(biāo)記每個輔助索引頁(space,page_no)的可用空間。這個就是Insert Buffer Bitmap,每個Insert Buffer Bitmap頁用來追蹤16384個輔助索引頁。每個輔助索引頁在Insert Buffer Bitmap存儲結(jié)構(gòu)如下:

IBUF_BITMAP_FREE IBUF_BITMAP_BUFFERED IBUF_BITMAP_IBUF
表示該輔助索引頁的可用空間(占用2個bit):
0 表示無可用空間
1 表示剩余空間>1/32
2 表示剩余空間>1/16
3 表示剩余空間>1/8
1 表示該輔助索引頁有記錄被緩存到Change Buffer中(占用1個bit) 1 表示該頁是Change Buffer B+ Tree的頁

Change Buffer工作狀態(tài)

可以通過SHOW ENGINE INNODB STATUS;查看Change Buffer工作狀態(tài):

image

如上圖所示,首先看下Ibuf那一行:

  • size:表示已經(jīng)合并到輔助索引頁的數(shù)量;
  • free list len:表示空閑列表長度;
  • seg size:表示當(dāng)前Change Buffer的大小,2*16KB;
  • merges:表示合并的次數(shù);
  • merged operations:表示每個具體操作合并的次數(shù);
    • insert:表示插入操作;
    • delete mark:表示刪除標(biāo)記操作;
    • delete:表示物理刪除操作;
  • discarded operations:表示操作的表已經(jīng)被刪除,不需要合并的每個具體操作次數(shù);

InnoDB提供了innodb_change_buffering配置,可選值如下:

選項 說明
inserts 插入緩沖;
deletes 刪除標(biāo)記緩沖;
changes 更新緩沖,由兩個上面inserts、deletes組成;
purges 緩沖在后臺發(fā)生的物理刪除操作;
all 表示啟用上面所有;
none 表示什么都不啟用;

Change Buffer合并操作觸發(fā)

  • 輔助索引頁被讀取到緩沖池:

    當(dāng)輔助索引頁被讀取到緩沖池時,需要檢查Insert Buffer Bitmap頁IBUF_BITMAP_BUFFERED==1?如果是,則觸發(fā)合并操作;
  • Insert Buffer Bitmap頁追蹤到改輔助索引頁無可用空間時:

    插入輔助索引頁時,檢測到此次插入后的輔助索引頁大小會<1/32,就會強(qiáng)制觸發(fā)合并操作;
  • Master Thread:每秒或每10秒觸發(fā)一次合并操作;在Change Buffer B+ Tree中,樹的節(jié)點根據(jù)(space, offset)排序。Master Thread會隨機(jī)選擇Change Buffer B+ Tree的一個節(jié)點,讀取從該節(jié)點開始到之后所需要的節(jié)點數(shù)量。比如Master Thread合并變更緩存的數(shù)量=5,那么就隨機(jī)選擇一個節(jié)點,從該節(jié)點之后的5個節(jié)點(包括第一個選中的節(jié)點)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容