【MySQL】Insert buffer 漫談
我們知道在進行插入操作時,資料頁的存放還是按主鍵id的執行順序存放, 但是對於非聚集索引,葉子節點的插入不再是順序的了。
例如,對於如下表結構進行insert操作
create table tab (
id int auto_increment,
name varchar(30),
primary key (id),
key(name)
) engine=innodb default charset=utf8;
nanme 為非唯一欄位,這時就需要離散地訪問非聚集索引頁,插入效能在這裡變低了。然而這並不是這個name欄位上索引的錯誤,因為B+樹的特性決定了非聚集索引插入的離散性。
為了解決非聚族索引的隨機寫效能差,InnoDB 儲存引擎開發了 innsert-buffer pool (5.5 中做了加強,稱之為 change buffer pool)
一 什麼是 innsert-buffer pool
innodb使用insert buffer"欺騙"資料庫:對於為非唯一索引,輔助索引的修改操作並非實時更新索引的葉子頁,而是把若干對同一頁面的更新快取起來做合併為一次性更新操作,轉化隨機IO 為順序IO,這樣可以避免隨機IO帶來效能損耗,提高資料庫的寫效能。
1.1 原理:
a 先判斷要更新的這一頁在不在記憶體中。
b 如果不在,則讀取index page 存入Insert Buffer,按照Master Thread的排程規則來合併非唯一索引和索引頁中的葉子結點.
1.2 Master Thread的排程規則
a 主動merger[innodb主執行緒定期完成,使用者執行緒無感知]
主動merger:
原理:主動merge透過innodb主執行緒(svr_master_thread)判斷:若過去1s之內發生的I/O小於系統I/O能力的5%,
則主動進行一次insert buffer的meger操作。meger的頁面數為系統I/O能力的5%,讀取採用async io模式。
每10s,必定觸發一次insert buffer meger操作。meger的頁面數仍舊為系統 I/O能力的5%。
步驟:
1.主執行緒發出async io請求,async讀取需要被meger的索引頁面
2.I/O handler 執行緒,在接受到完成的async I/O之後,進行merger
b 被動merge[使用者執行緒完成,使用者能感受到meger操作帶來的效能影響]
被動merge:
情況一:
insert操作,導致頁面空間不足,需要分裂(split)。由於insert buffer只針對單個頁面,不能buffer page split[頁已經在記憶體裡],因此引起頁面的被動meger。同理,update操作導致頁面空間不 足;purge導致頁面為空等。總之:若 當前操作引起頁面split or merge,那麼就會導致被動merge。
情況二:
insert操作,由於其它各種原因,insert buffer最佳化返回false,需要真正讀取page時,要進行被動merge。與一不同的是,頁在disk上,需要讀取到記憶體裡。
情況三:
在進行insert buffer操作,發現insert buffer太大,需要壓縮insert buffer,這時需要強制被動merge,不允許 insert 操作進行。
二 為什麼要求是非唯一索引呢?
因為
1 主鍵是行唯一的標示符,當app 寫入行時,是按照主鍵遞增的順序進行插入的,異常插入聚族索引一般也順序的,不需要隨機IO。
2 寫唯一索引要檢查記錄是不是存在,所以在修改唯一索引之前,必須把修改的記錄相關的索引頁讀出來才知道是不是唯一,這樣Insert buffer就沒意義了,反正要讀出來(讀帶來隨機IO),所以只對非唯一索引有效。
三 如何檢視insert buffer
我們可以透過show engine innodb status \G 來檢視插入緩衝的資訊
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 2920 merges
merged operations:
insert 23858, delete mark 0, delete 0
discarded operations:
insert 0, delete mark 0, delete 0
seg size顯示了當前插入緩衝的大小為2 *16KB,大約為32KB,free list len代表了空閒列表的長度,size代表了已經合併記錄頁的數量。merges 表示合併次數。
merged operations:
Inserts代表插入的記錄數,delete mark delete 次數均為0.
四 insert buffer 增強之 change buffering
change buffering 是MySQL5.5加入的新特性,change buffering是insert buffer的加強,insert buffer只針對insert有效,change buffering對insert、delete、update(delete+insert)、purge都有效。當修改一個索引塊(secondary index)時的資料時,索引塊在buffter pool中不存在,修改資訊就會被cache在change buffer中,當透過索引掃描把需要的索引塊讀取到buffer pool時,會和change buffer中修改資訊合併,再擇機寫回disk。目的還是為了減少隨機IO帶來效能損耗,說明白了:把隨機IO儘量變成順序IO。
五 小結
對於廉價的機械硬碟,這個引數還是能幫助提高效能的。在SSD盛行的今天,在SSD上隨機訪問和順序訪問效能幾乎差不多的情況下,insert buffer/change buffering特性不會帶來多大的效能提升。
六 參考文章
[1] Some little known facts about Innodb Insert Buffer
[2] innodb-performance-change_buffering
[3] mysql-5-5-innodb-change-buffering
[4]
例如,對於如下表結構進行insert操作
create table tab (
id int auto_increment,
name varchar(30),
primary key (id),
key(name)
) engine=innodb default charset=utf8;
nanme 為非唯一欄位,這時就需要離散地訪問非聚集索引頁,插入效能在這裡變低了。然而這並不是這個name欄位上索引的錯誤,因為B+樹的特性決定了非聚集索引插入的離散性。
為了解決非聚族索引的隨機寫效能差,InnoDB 儲存引擎開發了 innsert-buffer pool (5.5 中做了加強,稱之為 change buffer pool)
一 什麼是 innsert-buffer pool
innodb使用insert buffer"欺騙"資料庫:對於為非唯一索引,輔助索引的修改操作並非實時更新索引的葉子頁,而是把若干對同一頁面的更新快取起來做合併為一次性更新操作,轉化隨機IO 為順序IO,這樣可以避免隨機IO帶來效能損耗,提高資料庫的寫效能。
1.1 原理:
a 先判斷要更新的這一頁在不在記憶體中。
b 如果不在,則讀取index page 存入Insert Buffer,按照Master Thread的排程規則來合併非唯一索引和索引頁中的葉子結點.
1.2 Master Thread的排程規則
a 主動merger[innodb主執行緒定期完成,使用者執行緒無感知]
主動merger:
原理:主動merge透過innodb主執行緒(svr_master_thread)判斷:若過去1s之內發生的I/O小於系統I/O能力的5%,
則主動進行一次insert buffer的meger操作。meger的頁面數為系統I/O能力的5%,讀取採用async io模式。
每10s,必定觸發一次insert buffer meger操作。meger的頁面數仍舊為系統 I/O能力的5%。
步驟:
1.主執行緒發出async io請求,async讀取需要被meger的索引頁面
2.I/O handler 執行緒,在接受到完成的async I/O之後,進行merger
b 被動merge[使用者執行緒完成,使用者能感受到meger操作帶來的效能影響]
被動merge:
情況一:
insert操作,導致頁面空間不足,需要分裂(split)。由於insert buffer只針對單個頁面,不能buffer page split[頁已經在記憶體裡],因此引起頁面的被動meger。同理,update操作導致頁面空間不 足;purge導致頁面為空等。總之:若 當前操作引起頁面split or merge,那麼就會導致被動merge。
情況二:
insert操作,由於其它各種原因,insert buffer最佳化返回false,需要真正讀取page時,要進行被動merge。與一不同的是,頁在disk上,需要讀取到記憶體裡。
情況三:
在進行insert buffer操作,發現insert buffer太大,需要壓縮insert buffer,這時需要強制被動merge,不允許 insert 操作進行。
二 為什麼要求是非唯一索引呢?
因為
1 主鍵是行唯一的標示符,當app 寫入行時,是按照主鍵遞增的順序進行插入的,異常插入聚族索引一般也順序的,不需要隨機IO。
2 寫唯一索引要檢查記錄是不是存在,所以在修改唯一索引之前,必須把修改的記錄相關的索引頁讀出來才知道是不是唯一,這樣Insert buffer就沒意義了,反正要讀出來(讀帶來隨機IO),所以只對非唯一索引有效。
三 如何檢視insert buffer
我們可以透過show engine innodb status \G 來檢視插入緩衝的資訊
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 2920 merges
merged operations:
insert 23858, delete mark 0, delete 0
discarded operations:
insert 0, delete mark 0, delete 0
seg size顯示了當前插入緩衝的大小為2 *16KB,大約為32KB,free list len代表了空閒列表的長度,size代表了已經合併記錄頁的數量。merges 表示合併次數。
merged operations:
Inserts代表插入的記錄數,delete mark delete 次數均為0.
四 insert buffer 增強之 change buffering
change buffering 是MySQL5.5加入的新特性,change buffering是insert buffer的加強,insert buffer只針對insert有效,change buffering對insert、delete、update(delete+insert)、purge都有效。當修改一個索引塊(secondary index)時的資料時,索引塊在buffter pool中不存在,修改資訊就會被cache在change buffer中,當透過索引掃描把需要的索引塊讀取到buffer pool時,會和change buffer中修改資訊合併,再擇機寫回disk。目的還是為了減少隨機IO帶來效能損耗,說明白了:把隨機IO儘量變成順序IO。
五 小結
對於廉價的機械硬碟,這個引數還是能幫助提高效能的。在SSD盛行的今天,在SSD上隨機訪問和順序訪問效能幾乎差不多的情況下,insert buffer/change buffering特性不會帶來多大的效能提升。
六 參考文章
[1] Some little known facts about Innodb Insert Buffer
[2] innodb-performance-change_buffering
[3] mysql-5-5-innodb-change-buffering
[4]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30221425/viewspace-2134238/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【MySQL】四、Insert buffer 漫談MySql
- 【MySQL】MyRocks 漫談MySql
- 漫談mysql索引MySql索引
- Mysql核心:INNODB儲存引擎--《十一》Insert BufferMySql儲存引擎
- 【MySQL】漫談死鎖MySql
- 全網最清楚的:MySQL的insert buffer和change buffer 串講MySql
- MySQL Join BufferMySql
- UIAppearance漫談UIAPP
- 淺談HiZ-buffer
- MySQL中的Percona-toolkit工具由來漫談MySql
- MySQL INSERT DELAYEDMySql
- Mysql Key Buffer SizeMySql
- 漫談負載均衡負載
- 漫談CUDA優化優化
- 漫談Oracle RAC servicesOracle
- 程式語言漫談
- Oracle CPU TIME 漫談Oracle
- 隨機數漫談隨機
- MySQL 提高Insert效能MySql
- 漫談 SLAM 技術(上)SLAM
- PHP安全性漫談PHP
- iOS APP 架構漫談iOSAPP架構
- Hadoop Map Reduce 漫談Hadoop
- GIS資料漫談(三)
- 漫談Hadoop HDFS BalancerHadoop
- N進位制漫談
- 漫談Github與開源Github
- mysql change buffer小結MySql
- mysql insert導致死鎖MySql
- mysql insert的特殊用法MySql
- mysql INSERT ... ON DUPLICATE KEY UPDATEMySql
- babel知識體系漫談Babel
- 漫談Web快取架構Web快取架構
- 漫談網站優化提速網站優化
- [前端漫談_1] 從 for of 聊到 Generator前端
- 效能優化漫談之一優化
- 效能優化漫談之二優化
- 新特性:postgresql的vacuum漫談SQL