1. 程式人生 > >InnoDB Insert Buffer(插入緩沖)

InnoDB Insert Buffer(插入緩沖)

ring discard const 檢查 inno 鏈表 二級 今天 並且

InnoDB Insert Buffer(插入緩沖)

每個存儲存儲引擎自身都有自己的特性(決定性能以及更高可靠性),而InnoDB的關鍵特性有:

  • 插入緩沖(Insert Buffer)--》Change Buffer
  • 兩次寫(Double Write)
  • 自適應哈希索引(Adaptive Hash Page)
  • 異步IO(Async IO)
  • 刷新鄰接頁(Flush Neighbor Page)

今天主要聊一下插入緩沖(Insert Buffer)在InnoDB存儲引擎中的作用。

Insert Buffer其實是一種重要的數據變更日誌,在MySQL5.1 之前稱為Insert Buffer, 優化2級非唯一索引上插入操作的讀IO,在MySQL5.5之後改名為Change Buffer, 功能也擴展為2級非唯一索引上的插入、刪除、更新、purge的讀IO優化。也就是說Change buffer的主要目的是將對二級索引的數據操作緩存下來,以此減少二級索引的隨機IO,並達到操作合並的效果。值得提的一點是,Change Buffer也是物理頁的組成部分。

Change Buffer的核心思想,當數據庫需要對2級緩存進行修改時,是將這些更新緩存在內存中,在特定的條件下,統一將這些更新到相應的2級索引頁上,這樣做可以減少讀IO的次數,並且相鄰的頁的讀IO可以合並。之所以無法對主鍵和唯一索引進行優化是因為唯一性判斷需要讀取實際索引頁面中的數據,這就和Insert Buffer 減少讀 IO 的初衷背離了。在源碼中的命名一直還是用ibuf。
struct ibuf_struct{
  ulint size;  //當前ibuf btree 頁面數
  ulint max_size;  //ibuf最大頁面數
  ulint seg_size;  //所屬段的頁面數
  ibool empty; //是否為空   ulint free_list_len; //空閑鏈表長度   ulint height; //樹高度   dict_index_t* index; //ibuf索引   ulint n_merges; //合並的頁面數   ulint n_merged_ops[IBUF_OP_COUNT]; //各種操作合並的頁面數   ulint n_discarded_ops[IBUF_OP_COUNT]; //放棄的操作涉及的頁面數 };

從上述的結構體可以得知,Ibuf實際上也是一棵B+樹索引,它與innodb中其他的b+樹有著完全一樣的結構。Ibuf樹中的記錄其實就是包含了記錄本身,還有記錄所在頁面號的信息。

  值得註意的點是,ibuf只適用於 non-unique secondary indexes 也就是說只能用在非唯一的索引上,原因如下:

1. primary key 是按照遞增的順序進行插入的,異常插入聚族索引一般也順序的,非隨機IO

2. 寫唯一索引要檢查記錄是不是存在,所以在修改唯一索引之前,必須把修改的記錄相關的索引頁讀出來才知道是不是唯一、這樣ibuf就沒意義了,要讀出來(隨機IO)所以只對非唯一索引有意義。

ibuf可以對三種類型的操作進行緩存:INSERT、DELETE-MARK 、DELETE操作,前兩種對應用戶線程操作,第三種則由purge操作觸發。

用戶可以通過參數innodb_change_buffering來控制緩存何種操作:

static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
        "none",         /* IBUF_USE_NONE */
        "inserts",      /* IBUF_USE_INSERT */
        "deletes",      /* IBUF_USE_DELETE_MARK */
        "changes",      /* IBUF_USE_INSERT_DELETE_MARK */
        "purges",       /* IBUF_USE_DELETE */
        "all"           /* IBUF_USE_ALL */
};

ibuf默認值為all,表示緩存所有操作。註意由於在二級索引上的更新操作總是先delete-mark,再insert新記錄,因此update會產生兩條ibuf entry。

因此delete buffer對應update操作的第一個過程,即將記錄標記為刪除。purge buffer對應update操作的第二個過程,即將記錄真正的刪除。同時InnoDB存儲引擎提供了參數innodb_change_buffering,用來開啟各種buffer選項。該參數的可選值為:inserts、deletes、purges、changes、all、none。inserts、deletes、purges就是前面討論過的三種情況。changes表示啟用inserts和deletes,all表示啟用所有,none表示都不啟用。

InnoDB Insert Buffer(插入緩沖)