MySQLGroupCommit的優化

zhaiwx_yinfeng發表於2016-05-10

最近花了一些時間在做MySQL Group Commit的優化,關於Group commit的原理,這裡不再贅述,有興趣的可以翻閱我之前的部落格http://mysqllover.com/?p=581,這裡簡單描述下兩點優化,主要基於MySQL5.6.16

1.優化binlog_order_commits=0並且sync_binlog>0時的效能 
我們知道當binlog_order_commits關閉時,表示我們能接受binlog commit和innodb commit的順序不同(這不會帶來資料不一致,但可能會影響到熱備份),關閉該選項可以帶來一定程度的效能提升。

本優化也是基於該前提,假定sync_binlog =1000, 那麼在第1000組事務進入sync stage時,需要去做binlog sync,我們知道fsync操作是非常慢且耗時的操作,而第1001組事務,顯然無需去做sync,如果我們允許innodb/binlog commit失序,就可以讓第1001組事務跳過sync stage,直接進入innodb commit

detail見http://bugs.mysql.com/bug.php?id=73018,附加補丁

2.延遲寫redo直到group commit時來提升效能

我們知道MySQL使用Binlog,Innodb XA的方式來進行crash recovery,所有記錄在binlog中的事務我們都期望能夠commit掉;
這意味著,在寫binlog之前,需要確保事務的prepare狀態被寫到redo中,這樣才能從crash中恢復.

原生的邏輯中,各個事務各自做innodb prepare, 並寫redo log; 只有到了commit階段,進入ordered_commit,才進入組提交;

我們主要集中在group commit的第一階段:flush stage。 在該階段,leader執行緒從佇列中pop 執行緒加入queue,並依次flush thread cache到binlog檔案.

修改後的流程:
1. 在Innodb prepare階段不再write/sync redo log,而是直接返回

2.在group commit的flush stage階段,修改成如下邏輯
a) 收集組提交佇列
b) 呼叫ha_flush_logs 做一次redo write/sync
c) 將佇列中thd的所有binlog cache寫到binlog檔案中

detail見http://bugs.mysql.com/bug.php?id=73202, 附加補丁


相關文章