InnoDB 原理篇:Change Buffer 是如何提升索引性能的?

前言

大家好,我是阿星。

相信很多小夥伴設計索引時,考慮更多的是索引是否能覆蓋大部分的業務場景,卻忽略了索引的性能

什麼?不同的索引,性能還不一樣?

是的,這要從change buffer說起。

Change Buffer 是什麼

MySQL在啓動成功後,會向內存申請一塊內存空間,這塊內存空間稱爲Buffer Pool

Buffer Pool內維護了很多內容,比如緩存頁、各種鏈表、redo log buff、change buffer 等等

回到正題,change buffer是用來幹嘛的?

當索引字段內容發生更新時(update、insert、delete),要更新對應的索引頁,如果索引頁Buffer Pool裏命中的話,就直接更新緩存頁

否則,InnoDB會將這些更新操作緩存在change buffer中,這樣就無需從硬盤讀入索引頁

下次查詢索引頁時,會將索引頁讀入Buffer Pool,然後將change buffer中的操作應用到對應的緩存頁,得到最新結果,這個過程稱爲merge,通過這種方式就能保證數據邏輯的正確性。

不難看出,change buffer通過減少硬盤隨機 IO 讀提高內存利用率,讓數據庫的併發能力更強。

如果不瞭解 Buffer Pool、redo log、索引頁是什麼,可以看看阿星之前寫的幾篇文章

持久化

看到這裏小夥伴有疑問了,change buffer在內存中,如果萬一MySql實例掛了或宕機了,這次的更新操作不全丟了嗎?

其實不用擔心,InnoDB對這塊有相應的持久化方案,會有後臺線程定期把change buffer持久化到硬盤的系統表空間(ibdata1)。

並且每次change buffer記錄的內容,會寫入到redo log buff中,由後臺線程定期將redo log buff持久化到硬盤的redolog日誌。

最後MySql重啓,可以通過ibdata1redolog恢復change buffer,恢復的過程,分爲下面幾種情況

  1. change buffer的數據刷盤到ibdata,直接根據ibdata恢復

  2. change buffer的數據未刷盤,redolog裏記錄了change buffer的內容

如果不清楚redologbinlog的可以看看下面這幾篇文章

如何使用 Change Buffer

看到這裏,相信大家對change buffer有了基本的認識。

現在可以展開講講change buffer的使用限制。

是的,你沒聽錯,change buffer不能隨隨便便用。

一般我們可以把常用索引分類爲下面幾種

其中聚簇索引唯一索引是無法使用change buffer,因爲它們具備唯一性

當更新唯一索引字段的內容時,需要把相應的索引頁加載進Buffer Pool,驗證唯一性約束,此時都已經讀入到Buffer Pool了,那直接更新會更快,沒必要使用change buffer

也就是說,只有非唯一索引才能使用change buffer

業務場景

那現在有一個問題,使用change buffer一定可以起到加速作用嗎?

相信大家都清楚merge的時候是將change buffer記錄的操作應用到索引頁。

所以索引頁merge之前,change buffer記錄的越多收益就越大。

因此對於寫多讀少的業務場景,索引頁在寫完以後馬上被訪問到的概率很小,此時change buffer的收益最高。

相反,讀多寫少的業務場景,更新完馬上做查詢,則會觸發change buff立即merge, 不但硬盤隨機IO次沒有減少,還增加change buffer的維護成本。

因此change buff適合寫多讀少的業務場景

選擇索引

由於唯一索引用不上change buffer的優化機制,在業務可以接受的情況下,從性能角度出發建議考慮非唯一索引

如果所有的更新後面,都馬上伴隨着對這個記錄的查詢,應該關閉change bufferinnodb_change_buffering設置爲none表示關閉change buffer

而在其他情況下change buffer都能提升更新性能。

我們可以通過innodb_change_buffer_max_size來動態設置change buffer佔用的內存大小,假設參數設置爲50的時候,表示change buffer的大小最多隻能佔用buffer pool50%

最後留個思考題,如果知道redo log一定清楚WAL機制,change bufferWAL分別提升性能的側重點是什麼?

關於我

阿星是一個熱愛技術的 Java 程序猿,公衆號  「程序猿阿星」 定期分享有趣有料的精品原創文章!

程序猿阿星 一起成長進階!專注技術原理、源碼,通過圖解方式輸出技術,這裏將會分享操作系統、計算機網絡、Java、分佈式、數據庫等精品原創文章

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/S7-LI5FdfDuogFrN8vJZ8Q