InnoDB插入緩衝

InnoDB存儲引擎有三大特性非常令人激動,它們分別是插入緩衝、兩次寫和自適應哈希,本篇文章先介紹第一個特性 - 插入緩衝(insert buffer)
在上一篇《MySQL - 淺談InnoDB存儲引擎》中,我們可以看到在InnoDB的內存中有單獨一塊叫“插入緩衝”的區域,下面我們詳細來介紹它。

非聚集索引寫性能問題
爲了闡述非聚集索引寫性能問題,我們先來看一個例子:

mysql>create table t (
           id int auto_increment,
           name varchar(30),
           primary key (id)
           );

我們創建了一個表,表的主鍵是id,id列式自增長的,即當執行插入操作時,id列會自動增長,頁中行記錄按id順序存放,不需要隨機讀取其它頁的數據。因此,在這樣的情況下(即聚集索引),插入操作效率很高。
但是,在大部分應用中,很少出現表中只有一個聚集索引的情況,更多情況下,表上會有多個非聚集的secondary index (輔助索引)。比如,對於上一張表t,業務上還需要按非唯一的name字段查找,則表定義改爲:

mysql>create table t (
           id int auto_increment,
           name varchar(30),
           primary key (id),
           key (name)
           );

這時,除了主鍵聚合索引外,還產生了一個name列的輔助索引,對於該非聚集索引來說,葉子節點的插入不再有序,這時就需要離散訪問非聚集索引頁,插入性能變低。

插入緩衝技術機制
爲了解決這個問題,InnoDB設計出了插入緩衝技術,對於非聚集類索引的插入和更新操作,不是每一次都直接插入到索引頁中,而是先插入到內存中。具體做法是:如果該索引頁在緩衝池中,直接插入;否則,先將其放入插入緩衝區中,再以一定的頻率和索引頁合併,這時,就可以將同一個索引頁中的多個插入合併到一個IO操作中,大大提高寫性能。回憶一下在《MySQL - 淺談InnoDB存儲引擎》中提到的master thread主循環其中的一項工作就是每秒中合併插入緩衝(可能)。
這個設計思路和HBase中的LSM樹有相似之處,都是通過先在內存中修改,到達一定量後,再和磁盤中的數據合併,目的都是爲了提高寫性能,具體可參考《HBase LSM樹》,這又再一次說明,學到最後,技術都是相通的。
插入緩衝的啓用需要滿足一下兩個條件:

  • 1)索引是輔助索引(secondary index)
  • 2)索引不適合唯一的
    如果輔助索引是唯一的,就不能使用該技術,原因很簡單,因爲如果這樣做,整個索引數據被切分爲2部分,無法保證唯一性。

插入緩衝帶來的問題
任何一項技術在帶來好處的同時,必然也帶來壞處。插入緩衝主要帶來如下兩個壞處:
1)可能導致數據庫宕機後實例恢復時間變長。如果應用程序執行大量的插入和更新操作,且涉及非唯一的聚集索引,一旦出現宕機,這時就有大量內存中的插入緩衝區數據沒有合併至索引頁中,導致實例恢復時間會很長。
2)在寫密集的情況下,插入緩衝會佔用過多的緩衝池內存,默認情況下最大可以佔用1/2,這在實際應用中會帶來一定的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章