MySQL/InnoDB和GroupCommit(2)
今天發現Percona Release的Percona-Server-5-5-18-23-0已經完成了Group Commit工作,而且是用最優雅的方式(移植了MariaDB的實現,而不是workaround),心裡難掩激動。
這篇文章接前篇繼續介紹一下問題的背景:什麼是Group Commit,現在的官方版本Group Commit做到了什麼程度?
MySQL/InnoDB在做事務的時候使用的日誌先行(Write-ahead logging)的方式保證事務的快速和持久,所以每次事務完成都要求日誌必須持久化到磁碟,在Linux上對應的操作就是“write and fsync”,write速度是很快的,一般對應的寫Page Cache,而fsync則要求檔案系統把對應檔案的哦Page Cache必須持久化到磁碟上,而對於傳統磁碟一次寫操作大約需要1~3ms(不說BBU),這意味著對於傳統磁碟1秒鐘最多最多做333~1000個事務,這是不理想的,對硬體的利用率(吞吐量)也是非常低。
所以,這裡就有了Group操作的概念,即當好幾個執行緒都要fsync同一個日誌檔案時,我們將這些fsync合併到一次來做。簡單舉例:我們讓系統每2ms做一次fsync,這樣如果這2ms內有100個執行緒都需要做fsync,那就賺到了,原本100個fsync都獨立來做那耗時會非常多的。
你肯定會說,難道這不是很簡單的想法嗎?是的,這就是原本是很簡單、也很自然的想法。
但對MySQL來說卻變成了一種奢求(看看這個Bug討論)。
MySQL是不是太弱了,這麼簡單的事情都搞不定?不是的。
MySQL從開源到現在,成功的一個非常重要的原因,就是MySQL的外掛式架構。如果MySQL只是MyISAM估計不會有現在的流行程度,外掛式的架構讓諸如Heikki Tuuri有了發揮空間,在InnoDB和MySQL一起時,MySQL才能算是一個真正的DBMS。再到後來,有Infobright、 FEDERATED、PBXT等等。
外掛式的架構給MySQL帶來了活力,做出犧牲便是在上層(MySQL)和下層(儲存引擎)互動時帶來的額外消耗,有時甚至上層和下層需要做一些重複工作。無法做Group Commit就是這其中的犧牲之一。
InnoDB在一次事務中,有兩次fsync,分別是prepare階段和commit階段,對於這兩次操作InnoDB都是實現了Group操作的。
如果你設定了binlog_sync=1,則又多了一次fsync操作(參考MYSQL_BIN_LOG::flush_and_sync),這次操作在innobase_xa_prepare和innodb_commit之間:
binlog_prepare (do nothing)
innodb_prepare
…
binlog_commit
innobase_commit
這次fsync,在MySQL中一直都無法做Group。所以,一直以來當innodb_flush_log_at_trx_commit和binlog_sync都等於1的時候,MySQL的效能就非常、非常糟糕。原因是為了保證InnoDB內部Commit的順序和MySQL日誌的順序一致(參考)。
難道沒人去解決這個問題嗎?不是的。有很多人已經做出了努力,直到Kristian Nielsen@MariaDB提出了理論和實際上的最優解決方案。
Mark Callaghan@Facebook關於Group Commit做的工作:FB的基本實現 | FB的問題和改進 | 效能 | 對比MariaDB的實現(對比的結果是MariaDB完勝,無論是方案架構還是效能)
Facebooke可以說是通過一個Trick快速實現了Group Commit。而Kristian Nielsen@MariaDB這是從架構上根本的解決了這個問題。
MariaDB關於Group Commit架構和實現: WL116 | WL132 | WL164
後面還有很多值得寫的,我希望自己能夠一直寫完這個系列。
相關文章
- MYSQL之 GroupCommitMySqlMIT
- mysql innodb的行鎖(2)MySql
- 重新學習Mysql資料庫2:『淺入淺出』MySQL 和 InnoDBMySql資料庫
- mysql事務和鎖InnoDBMySql
- MySQL/InnoDB和Group CommitMySqlMIT
- 『淺入淺出』MySQL 和 InnoDBMySql
- MySQL InnoDB Update和Crash Recovery流程MySql
- MYSQL和INNODB分層實現MySql
- Mysql innodb引擎(一)緩衝和索引MySql索引
- Mysql 中 MyISAM 和 InnoDB 的區別MySql
- mysql innodb_log_file_size 和innodb_log_buffer_size引數MySql
- MySQL InnoDB 索引MySql索引
- 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】5.6.x InnoDB Error Table mysql.innodb_table_stats not foundMySqlError
- MySQL技術內幕 InnoDB儲存引擎 第2版MySql儲存引擎
- 初觸hibernate01--MYSQL建表時type=InnoDB和Engine=InnoDB注意點MySql
- Mysql中myisam和innodb的區別,至少5點MySql
- MYSQL INNODB主鍵使用varchar和int的區別MySql
- Mysql引擎中MyISAM和InnoDB的區別有哪些?MySql
- mysql innodb_deadlock_detect檢測和處理MySql
- Mysql innodb引擎(二)鎖MySql
- MySQL InnoDB髒頁管理MySql
- MySQL InnoDB緩衝池MySql
- MySQL 5.7 InnoDB Tablespace EncryptionMySql
- mysql innodb的行鎖MySql
- MySQL InnoDB表的限制MySql
- MySQL InnoDB版本一覽MySql
- xtrabackup備份mysql innodbMySql
- Mysql之新增innodb支援MySql
- MySQL: InnoDB 還是 MyISAM?MySql
- Experts in MySQL and InnoDB Performance.MySqlORM
- MySQL InnoDB儲存引擎MySql儲存引擎