MySQL/InnoDB和Group Commit
https://www.percona.com/blog/2011/07/13/testing-the-group-commit-fix/
http://blog.itpub.net/22664653/viewspace-1063134/
簡單的,InnoDB在每次提交事務時,為了保證資料已經持久化到磁碟(Durable),需要呼叫一次fsync(或者是fdatasync、或者使用O_DIRECT選項等)來告知檔案系統將可能在快取中的資料重新整理到磁碟(更多關於)。而fsync操作本身是非常“昂貴”的(關於“昂貴”:消耗較多的IO資源,響應較慢):傳統硬碟(10K轉/分鐘)大約每秒支撐150個fsync操作,SSD(Intel X25-M)大約每秒支撐1200個fsync操作。所以,如果每次事務提交都單獨做fsync操作,那麼這裡將是系統TPS的一個瓶頸。所以就有了Group Commit的概念。
當多個事務併發時,我們讓多個都在等待fsync的事務一起合併為僅呼叫一次fsync操作。這樣的一個簡單的最佳化將大大提高系統的吞吐量,Yoshinori Matsunobu的實驗表明,這將帶來五到六倍的效能提升。
MySQL/InnoDB在做事務的時候使用的日誌先行()的方式保證事務的快速和持久,所以每次事務完成都要求日誌必須持久化到磁碟
為了保證資料已經持久化到磁碟(Durable),需要呼叫一次fsync(或者是fdatasync、或者使用O_DIRECT選項等)來告知檔案系統將可能在快取中的資料重新整理到磁碟(更多關於)。而fsync操作本身是非常“昂貴”的(關於“昂貴”:消耗較多的IO資源,響應較慢):傳統硬碟(10K轉/分鐘)大約每秒支撐150個fsync操作,SSD(Intel X25-M)大約每秒支撐1200個fsync操作。所以,如果每次事務提交都單獨做fsync操作,那麼這裡將是系統TPS的一個瓶頸。
在Linux上對應的操作就是“”,write速度是很快的,一般對應的寫Page Cache,而fsync則要求檔案系統把對應檔案的哦Page Cache必須持久化到磁碟上,而對於傳統磁碟一次寫操作大約需要1~3ms(不說BBU),這意味著對於傳統磁碟1秒鐘最多最多做333~1000個事務,這是不理想的,對硬體的利用率(吞吐量)也是非常低。
所以,這裡就有了Group操作的概念,即當好幾個執行緒都要fsync同一個日誌檔案時,我們將這些fsync合併到一次來做。簡單舉例:我們讓系統每2ms做一次fsync,這樣如果這2ms內有100個執行緒都需要做fsync,那就賺到了,原本100個fsync都獨立來做那耗時會非常多的。
MySQL5.0開始,InnoDB就不再支援Group Commit了。在2005年,Peter Zaitsev就將此作為一個提交,直到2009年在InnoDB Plugin1.0.4才將此問題修復。
究其更本原因發現,5.0之後MySQL開始支援“分散式事務和兩階段提交協議”(distributed transactions and Two Phase Commit /2PC),在程式碼實現時為了保證Binlog中的事務順序和InnoDB Log(Transaction Log或者叫redo log)事務順序一致,被動放棄了Group Commit。如果Binlog順序不一致,那麼備庫就無法確保和主庫有一致的資料。
InnoDB本身的程式碼實現是可以支援Group Commit的,我們來看下面的程式碼:
如果你設定了binlog_sync=1,則又多了一次fsync操作(參考MYSQL_BIN_LOG::flush_and_sync),這次操作在innobase_xa_prepare和innodb_commit之間:
binlog_prepare (do nothing)
innodb_prepare(innobase_xa_prepare)
...
binlog_commit
innobase_commit
write() and fsync() binary log
innobase_commit()
在innobase_xa_prepare函式中需要獲取排他鎖,直到上面的innodb_commit結束鎖才釋放,所以上面的binlog write and fsync也就無法Group操作了(當binlog_sync=1時)InnoDB就無法做Group_commit了,如果prepare_commit_mutex提前釋放了,則可能導致InnoDB內部的事務順序和Binlog內部事務的順序不一致(: [12254|12408|12553|12810].html)。
當sync_binlog=1 和innodb-flush-log-at-trx-commit=1 同時啟用時,在寫密集的環境中效能的急劇下降
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26250550/viewspace-1674192/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql sync_binlog和 innodb_flush_log_at_trx_commitMySqlMIT
- innodb_flush_method和innodb_flush_log_at_trx_commitMIT
- MySQL:Innodb:innodb_flush_log_at_trx_commit引數影響的位置MySqlMIT
- mysql效能引數innodb_flush_log_at_trx_commitMySqlMIT
- MarriDB/MySQL的binlog group commit技術介紹MySqlMIT
- innodb_flush_log_at_trx_commit和sync_binlog innodb_flush_methodMIT
- MysqL 磁碟寫入策略之innodb_flush_log_at_trx_commitMySqlMIT
- mysql的innodb_flush_log_at_trx_commit引數實驗MySqlMIT
- mysql的order by和group byMySql
- innodb_flush_log_at_trx_commitMIT
- MySQL:Innodb 關於Handler_commit每次DML增加2的原因MySqlMIT
- 【MySQL】sync_binlog innodb_flush_log_at_trx_commit 淺析MySqlMIT
- sync_binlog和innodb_flush_log_at_trx_commit解析MIT
- 【MySQL】五、sync_binlog innodb_flush_log_at_trx_commit 淺析MySqlMIT
- mysql事務和鎖InnoDBMySql
- MySQL/InnoDB和GroupCommit(2)MySqlMIT
- 『淺入淺出』MySQL 和 InnoDBMySql
- MySQL InnoDB Update和Crash Recovery流程MySql
- MYSQL和INNODB分層實現MySql
- mysql插入慢之所innodb_flush_log_at_trx_commit引數的意義MySqlMIT
- mysql order by 和 group by 順序問題MySql
- Oracle和MySQL分組查詢GROUP BYOracleMySql
- MySQL Group ReplicationMySql
- Mysql innodb引擎(一)緩衝和索引MySql索引
- Mysql 中 MyISAM 和 InnoDB 的區別MySql
- mysql innodb_log_file_size 和innodb_log_buffer_size引數MySql
- MySQL InnoDB 索引MySql索引
- MySQL 中的 distinct 和 group by 的效能比較MySql
- innodb_flush_log_at_trx_commit引數的直白理解MIT
- mysql innodb索引高度MySql索引
- MySQL InnoDB update流程MySql
- MySQL Deadlocks in InnoDBMySql
- MySQL儲存引擎:MyISAM和InnoDB的區別MySql儲存引擎
- MySQL中myisam和innodb有什麼差異?MySql
- mysql的innodb和myisam的dml效能對比MySql
- Mysql innodb引擎和myisam引擎使用索引區別MySql索引
- 【Mysql】MySQL5.7.17- Group Replication搭建MySql
- 【MySQL】5.6.x InnoDB Error Table mysql.innodb_table_stats not foundMySqlError