MySQL 資料庫的提速器-寫快取(Change Buffer)

平頭哥的技術博文發表於2020-02-27

寫快取(Change Buffer) 是一種特殊的資料結構,用於在對資料變更時,如果資料所在的資料頁沒有在 buffer pool 中的話,在不影響資料一致性的前提下,InnoDB 引擎會將對資料的操作快取在 Change Buffer 中,這樣就省去了從磁碟中讀入這個資料頁。

將資料頁從磁碟讀入記憶體中涉及隨機 IO 訪問,這也是資料庫裡面成本最高的操作之一,而利用寫快取(Change Buffer)可以減少 IO 操作,從而提升資料庫效能。

關於 MySQL 寫快取(Change Buffer),我們先來看看 InnoDB 的技術架構圖:

InnoDB 架構圖

Change Buffer 是 Buffer Pool 中的一部分,雖然 Change Buffer 名字叫 Buffer ,但是它也是可以持久化的,在右邊的 System Tablespace 中可以看到持久化 Change Buffer 的空間。觸發寫快取(Change Buffer)持久化操作有以下幾種情況:

  • 1、資料庫空閒時,後臺有執行緒定時持久化
  • 2、資料庫緩衝池不夠用時
  • 3、資料庫正常關閉時
  • 4、redo log 寫滿時

再單獨看看 Change Buffer 的架構圖,如下所示:

Change Buffer 的架構圖

圖中詳細的描述了 Change Buffer 的功能,Change Buffer 中的資料最終還是會刷回到資料所在的原始資料頁中,Change Buffer 資料應用到原始資料頁,得到新的資料頁的過程稱之為 merge。merge 過程中只會將 Change Buffer 中與原始資料頁有關的資料應用到原始資料頁,以下三種情況會發生 merge 操作:

  • 1、原始資料頁載入到 Buffer Pool 時。
  • 2、系統後臺定時觸發 merge 操作。
  • 3、MySQL 資料庫正常關閉時。

Change Buffer 的相關設定

上面就是寫快取(Change Buffer)的相關知識,寫快取(Change Buffer)我們也是可以使用命令引數來控制,MySQL 資料庫提供了兩個對寫快取(Change Buffer)的引數。

Change Buffer 引數

1、innodb_change_buffer_max_size

innodb_change_buffer_max_size 表示 Change Buffer 最大大小佔 Buffer Pool 的百分比,預設為 25%。最大可以設定為 50%。

2、innodb_change_buffering

innodb_change_buffering 引數用來控制對哪些操作啟用 Change Buffer 功能,預設是:all。innodb_change_buffering 引數有以下幾種選擇:

--all:      預設值。開啟buffer inserts、delete-marking operations、purges
--none: 不開啟change buffer
--inserts:  只是開啟buffer insert操作
--deletes:  只是開delete-marking操作
--changes:  開啟buffer insert操作和delete-marking操作
--purges:   對只是在後臺執行的物理刪除操作開啟buffer功能
複製程式碼

對上面寫快取(Change Buffer)如果你還是雲裡霧裡的話,那麼我們就用一個案例來說明一下 Change Buffer ,首先我們向資料庫中插入兩條資料:

mysql> insert into t(id,k) values(id1,k1),(id2,k2);
複製程式碼

結合下面這張圖來分析這兩條插入語句。

圖片來源極客時間

假設當前是 K索引樹的狀態,K1 所在的資料頁 page1 在 Buffer Pool 中,k2 所在的資料頁不在 Buffer Pool 中,來看看這兩條語句的執行流程:

1、對於 k1 這條資料,Page 1 在記憶體中,所以直接更新記憶體,不會使用到 Change Buffer;

2、k2 對應的資料頁 Page 2 沒有在記憶體中,就在記憶體的 change buffer 區域,記錄下“我要往 Page 2 插入一行”這個資訊,這個地方及其關鍵,並沒有從磁碟中將 page2 載入到記憶體。

3、將上述兩個動作記入 redo log 中(圖中 3 和 4)。

4、後臺執行緒會定時將 page1 和 Change Buffer 中的資料持久化

主要地方在於步驟二,這就是寫快取(Change Buffer)提高效能的地方,雖然 page2 並沒有在記憶體中,但是並沒有妨礙我們往資料庫 page2 中插入資料,這就是寫快取(Change Buffer)的巧妙之處,也是寫快取(Change Buffer)提高 MySQL 的地方。

Change Buffer 適用場景

Change Buffer 並不是適用於所有場景,以下兩種情況不適合開啟 Change Buffer :

  • 1、資料庫都是唯一索引

如果資料庫都是唯一索引,那麼在每次操作的時候都需要判斷索引是否有衝突,勢必要將資料載入到快取中對比,因此也用不到 Change Buffer。

  • 2、寫入一個資料後,會立刻讀取它

寫入一個資料後,會立刻讀取它,那麼即使滿足了條件,將更新先記錄在 change buffer,但之後由於馬上要訪問這個資料頁,會立即觸發 merge 過程。這樣隨機訪問 IO 的次數不會減少,反而增加了 change buffer 的維護代價。所以,對於這種業務模式來說,change buffer 反而起到了副作用。

以下幾種情況開啟 Change Buffer,會使得 MySQL 資料庫明顯提升

  • 1、資料庫大部分是非唯一索引
  • 2、業務是寫多讀少
  • 3、寫入資料之後並不會立即讀取它

總體來說 InnoDB 的寫快取(Change Buffer)應用得當,會極大提高 MySQL 資料庫的效能,使用不恰當的話,可能會適得其反。

以上就是今天分享的內容,希望對您的學習或者工作有所幫助,如果您覺得文章不錯,歡迎點個贊和轉發,謝謝。

最後

目前網際網路上很多大佬都有 MySQL 相關文章,如有雷同,請多多包涵了。原創不易,碼字不易,還希望大家多多支援。若文中有所錯誤之處,還望提出,謝謝。

歡迎掃碼關注微信公眾號:「網際網路平頭哥」,和平頭哥一起學習,一起進步。

網際網路平頭哥

相關文章