共計(jì) 2542 個(gè)字符,預(yù)計(jì)需要花費(fèi) 7 分鐘才能閱讀完成。
mysql 中的 change buffer 是什么,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面丸趣 TV 小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
首先:正常 insert 的時(shí)候,也是首先要判斷哪個(gè)物理頁(yè) (包括數(shù)據(jù)頁(yè)和索引頁(yè)) 可以 insert,然后把這個(gè)物理塊讀取到 buffer pool,然后再在內(nèi)存執(zhí)行 insert 操作,然后再刷新到磁盤;
0)Change Buffer 為何提高性能
它緩存的是一個(gè)索引頁(yè)的 dml 的操作,而不是具體的數(shù)據(jù)頁(yè),具體的數(shù)據(jù)頁(yè)直接就修改了,對(duì)非聚集非唯一的索引頁(yè)修改的時(shí)候才可能用到 change buffer。當(dāng) buffer pool 中沒有某個(gè)索引頁(yè),并且需要 dml 操作這個(gè)索引頁(yè)的數(shù)據(jù)的時(shí)候,不需要先從磁盤讀取該索引頁(yè)到 buffer pool,直接把該操作記錄到 cahnge buffer 中,這里就減少了一次隨機(jī) io,然后等下次業(yè)務(wù)需要訪問這個(gè)索引頁(yè)的時(shí)候,再把這個(gè)頁(yè)讀取到 buffer poo 中,然后 change buffer 記錄的操作和 buffer pool 中剛讀進(jìn)來(lái)的索引頁(yè)進(jìn)行 merge 操作。
提高性能的地方還有一點(diǎn)是:對(duì)于非聚集非唯一索引的更新或者插入操作,不是每次插入或者更新操作完,都直接插入到索引頁(yè)中,而是先判斷插入的非聚集索引頁(yè)是否在緩沖池中,如果在,則直接插入,不在則放到 change buffer 中,然后以一定的頻率和情況進(jìn)行 change buffer 和輔助索引葉子的 merge(合并)操作,這時(shí)通常可以將多個(gè)索引葉子的 dml 操作合并到一個(gè)操作里(因?yàn)樵谝粋€(gè)索引頁(yè)中),這里也提高了性能
綜上所述 cahnge buffer 性能的提升在于兩點(diǎn):
一:當(dāng)需要修改的索引頁(yè)不在 buffer pool 的時(shí)候,不需要先把索引頁(yè)讀取到 buffer pool, 這里減少了 io
二:將多個(gè)索引葉子的 dml 操作合并到一個(gè)操作里(因?yàn)樵谝粋€(gè)索引頁(yè)中),批量 merge,這里也提高了性能;
1)change buffer 的內(nèi)容
Change Buffer 是一種特殊的數(shù)據(jù)結(jié)構(gòu),緩存對(duì)二級(jí)索引頁(yè)面的更改并且這些頁(yè)面不在 Buffer Pool 中(注意緩存的是對(duì)索引葉子的修改,而不是具體的索引葉子)。緩存的 changes 可能由 Insert、Delete 和 Update 的結(jié)果導(dǎo)致。稍后在頁(yè)面被其他讀取操作加載到 Buffer Pool 的時(shí)候合并,
簡(jiǎn)而言之:Change buffer 的主要目的是將對(duì)二級(jí)索引的數(shù)據(jù)操作緩存下來(lái),以此減少二級(jí)索引的隨機(jī) IO,并達(dá)到操作合并的效果。
3)change buffer 只針對(duì)輔助索引而言
對(duì)主鍵索引無(wú)效; 對(duì)輔助索引葉子節(jié)點(diǎn)的更改才可能借助 change buffer , 如果該列上沒有索引,那么就不會(huì)借助 change buffer 了!
4)緩沖池有 change buffer 信息固然不錯(cuò),但他不是單純是緩存池的一部分,change buffer 和數(shù)據(jù)頁(yè)一樣,change buffer 是一個(gè) B + 樹,放在共享表空間,默認(rèn)也就是 idbata1,向 change buffer 寫數(shù)據(jù)也是需要隨機(jī) io, 但有 change buffer 后,當(dāng) buffer 中沒有需要修改的葉子塊的時(shí)候,你不需要把葉子塊讀進(jìn) innodb_buffer_cahce 中 (減少的就是這里的 io) 只需要把改變寫進(jìn) cahnge buffer 即可,然后 cahnge buffer 中排序最后等待和真正的葉子節(jié)點(diǎn)數(shù)據(jù)合并! 批量合并! 所以如果更新操作不頻繁的時(shí)候,并且更新后立馬需要讀取該頁(yè)的時(shí)候,change buffer 的機(jī)制會(huì)增加部分 io 消耗! change buffer 減少了從內(nèi)存讀取硬盤的隨機(jī)讀 IO(數(shù)據(jù)頁(yè))操作,換做成批量順序 merge,redo log 減少了隨機(jī)寫 log 操作
5). 之所以需要滿足索引是輔助索引,并且是非唯一的
因?yàn)樵诓迦刖彌_時(shí),數(shù)據(jù)庫(kù)并不去查找索引頁(yè)來(lái)判斷插入的記錄的唯一性,如果去查找肯定又會(huì)有離散讀取的情況發(fā)生(隨機(jī) io),從而導(dǎo)致 change buffer 失去意義!
6) change buffer 的相關(guān)參數(shù)
1 innodb_change_buffering 默認(rèn)是 all 支持所有 DML 操作
2 innodb_change_buffer_max_size,默認(rèn)是 25,即緩沖池的 1 /4。最大可設(shè)置為 50, 采用默認(rèn)即可
7). 合并的操作是在 buffer pool 里面進(jìn)行的
當(dāng)下一次需要加載這個(gè)頁(yè)面的時(shí)候,也就是這個(gè)頁(yè)面有需求的時(shí)候,會(huì)將 Change Buffer 內(nèi)的更改合并到 Buffer Pool,隨后當(dāng)服務(wù)器在空閑的時(shí)候,這個(gè)更改會(huì)刷到 disk(磁盤)上, 或者在不繁忙的時(shí)候進(jìn)行 merge,這時(shí)候 merger 操作也是發(fā)生在 buffer pool;
8). 為什么 change buffer 存的是 buffer pool 中沒有的索引頁(yè)的操作?
因?yàn)槿绻?buffer pool 中,那么就直接 dml 操作對(duì)應(yīng)的索引頁(yè)了,change buffer 存在就是為了當(dāng)需要操作的索引頁(yè)不在 buffer pool 中,然后不需要立馬去磁盤讀取該索引頁(yè),只有當(dāng) buffer pool 中不存在的時(shí)候才可能用到 change buffer;
9) 除了數(shù)據(jù)頁(yè)被訪問,還有哪些場(chǎng)景會(huì)觸發(fā)刷寫緩沖中的數(shù)據(jù)呢?
還有這么幾種情況,會(huì)刷寫緩沖中的數(shù)據(jù):
(1)有一個(gè)后臺(tái)線程,會(huì)認(rèn)為數(shù)據(jù)庫(kù)空閑時(shí);
(2)數(shù)據(jù)庫(kù)緩沖池不夠用時(shí);
(3)數(shù)據(jù)庫(kù)正常關(guān)閉時(shí);
(4)redo log 寫滿時(shí);
畫外音:幾乎不會(huì)出現(xiàn) redo log 寫滿,此時(shí)整個(gè)數(shù)據(jù)庫(kù)處于無(wú)法寫入的不可用狀態(tài)。
10)什么業(yè)務(wù)場(chǎng)景,適合開啟 InnoDB 的寫緩沖機(jī)制?
先說(shuō)什么時(shí)候不適合,如上文分析,當(dāng):
(1)數(shù)據(jù)庫(kù)都是唯一索引;
(2)或者,寫入一個(gè)數(shù)據(jù)后,會(huì)立刻讀取它;
這兩類場(chǎng)景,在寫操作進(jìn)行時(shí)(進(jìn)行后),本來(lái)就要進(jìn)行進(jìn)行頁(yè)讀取,本來(lái)相應(yīng)頁(yè)面就要入緩沖池,此時(shí)寫緩存反倒成了負(fù)擔(dān),增加了復(fù)雜度。
什么時(shí)候適合使用寫緩沖,如果:
(1)數(shù)據(jù)庫(kù)大部分是非唯一索引;
(2)業(yè)務(wù)是寫多讀少,或者不是寫后立刻讀取;
可以使用寫緩沖,將原本每次寫入都需要進(jìn)行磁盤 IO 的 SQL,優(yōu)化定期批量寫磁盤。
畫外音:例如,賬單流水業(yè)務(wù)。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注丸趣 TV 行業(yè)資訊頻道,感謝您對(duì)丸趣 TV 的支持。