前段時間看了下姜老師寫的一個相關(guān)文章P8級面試難題,after_sync vs after_commit,哪個性能更好
寫的特別詳細(xì),很有收獲,這里結(jié)合一些之前看到的其他介紹,簡單的匯總整理下.
首先了解下兩個參數(shù)的區(qū)別
after_commit在主機(jī)事務(wù)提交后將日志傳送到從機(jī)逼友,after_sync是先傳再提交步责。
上圖文字說明可能大家感覺不是太直觀具體,如果在源碼層區(qū)分估計理解更加深些,參考[MySQL層事務(wù)提交流程簡析](https://mp.weixin.qq.com/s/4Plg7Bc1KDuhKD5fqx6NSA
從圖中可以看出在設(shè)置為after_sync時,則在第21步后確認(rèn),after_commit則在24步后確認(rèn).
可以看出after_commit如果在主庫掛的時候,可能會導(dǎo)致數(shù)據(jù)丟失,而after_sync則不會丟失數(shù)據(jù),但是可能在主庫正要返回提交成功給客戶端的時間點掛掉則會導(dǎo)致用戶以為沒有寫入成功,但是從庫已經(jīng)存在數(shù)據(jù)的情況.
因此如果業(yè)務(wù)無法接受數(shù)據(jù)丟失的話推薦使用after_sync.
性能對比(來自姜老師分享文章)
一個事務(wù)在半同步模式下提交鸿秆,無論是after_sync還是after_commit龙优,都要經(jīng)歷4個階段:
- InnoDB Redo File Write
- binlog File Flush & Sync
- InnoDB Redo File Commit(同時釋放事務(wù)持有的鎖)
- Send binlog to Slave
after_sync模式下尽爆,4個階段的順序為1->2->4->3抬伺,after_commit模式為1->2->3->4螟够。這個順序也解釋了為什么after_commit為什么會有“幻讀”問題。
現(xiàn)在假設(shè)階段1、2妓笙、3各需要1ms時間若河,階段4需要0.2ms時間,那么一次事務(wù)提交的時間:
T after_sync = 1 + 1 + 0.2 + 1 = 3.2 ms
T after_commit = 1 + 1 + 0.2 + 1 = 3.2 ms
以下分單線程,多線程對比下執(zhí)行時間
單線程情況下
-
after_sync 提交流程
image.png -
after_commit 提交流程
image.png
可見單線程下after_commit性能較佳(如果主從不在相同機(jī)房,時間較長時,after_commit理論上會比after_sync單線程性能強(qiáng)很多)
多線程
在并發(fā)的場景下寞宫,若事務(wù)之間的修改不沖突萧福,則事務(wù)是可以同時提交的,也就是可以進(jìn)入到組提交(Group Commit)優(yōu)化流程中辈赋。那么這時鲫忍,事務(wù)的提交變?yōu)榱耍?/p>
事務(wù)TX1~TX4可以同時進(jìn)入到提交階段,這時會進(jìn)入到MySQL的組提交優(yōu)化中钥屈。這時產(chǎn)生的優(yōu)化效果有:
InnoDB Redo Prepare只需要一次I/O操作
InnoDB binlog Write只需要一次I/O操作
接收到ACK后喚醒事務(wù)提交隊列只需要一次
可以看到有組提交加持下數(shù)據(jù)庫的的性能提升是非常明顯的悟民,假設(shè)沒有組提交,并且喚醒等待線程需要0.02ms篷就,則沒有組提交的情況下射亏,TX1~TX4事務(wù)所需要的時間為:
T[1~4 ]= ( 1 + 1 + 1 + 0.2 + 0.02 ) * 4 = 12.88 ms
在有組提交的優(yōu)化加持下,TX1~TX4事務(wù)所需要的時間優(yōu)化為了:
T[1~4] = 1 + 1 + 1 + 0.2 + 0.02 = 3.22 ms