最近花了一些時間在做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, 附加更新檔