MySQL組提交group commit詳解
引 言

前提:
- 以下討論的前提 是設(shè)置MySQL的crash safe相關(guān)參數(shù)為雙1:
sync_binlog=1
innodb_flush_log_at_trx_commit=1
背景說(shuō)明:
- WAL機(jī)制 (Write Ahead Log)定義: WAL指的是對(duì)數(shù)據(jù)文件進(jìn)行修改前,必須將修改先記錄日志。MySQL為了保證ACID中的一致性和持久性,使用了WAL。
- Redo log的作用: Redo log就是一種WAL的應(yīng)用。當(dāng)數(shù)據(jù)庫(kù)忽然掉電,再重新啟動(dòng)時(shí),MySQL可以通過(guò)Redo log還原數(shù)據(jù)。也就是說(shuō),每次事務(wù)提交時(shí),不用同步刷新磁盤數(shù)據(jù)文件,只需要同步刷新Redo log就足夠了。相比寫數(shù)據(jù)文件時(shí)的隨機(jī)IO,寫Redo log時(shí)的順序IO能夠提高事務(wù)提交速度。
- 組提交的作用:
- 在沒(méi)有開(kāi)啟binlog時(shí)
Redo log的刷盤操作將會(huì)是最終影響MySQL TPS的瓶頸所在。為了緩解這一問(wèn)題,MySQL使用了組提交,將多個(gè)刷盤操作合并成一個(gè),如果說(shuō)10個(gè)事務(wù)依次排隊(duì)刷盤的時(shí)間成本是10,那么將這10個(gè)事務(wù)一次性一起刷盤的時(shí)間成本則近似于1。
- 當(dāng)開(kāi)啟binlog時(shí)
為了保證Redo log和binlog的數(shù)據(jù)一致性,MySQL使用了二階段提交,由binlog作為事務(wù)的協(xié)調(diào)者。而 引入二階段提交 使得binlog又成為了性能瓶頸,先前的Redo log 組提交 也成了擺設(shè)。為了再次緩解這一問(wèn)題,MySQL增加了binlog的組提交,目的同樣是將binlog的多個(gè)刷盤操作合并成一個(gè),結(jié)合Redo log本身已經(jīng)實(shí)現(xiàn)的 組提交,分為三個(gè)階段(Flush 階段、Sync 階段、Commit 階段)完成binlog 組提交,最大化每次刷盤的收益,弱化磁盤瓶頸,提高性能。
圖解:
下圖我們假借“渡口運(yùn)輸”的例子來(lái)看看binlog 組提交三個(gè)階段的流程:

在MySQL中每個(gè)階段都有一個(gè)隊(duì)列,每個(gè)隊(duì)列都有一把鎖保護(hù),第一個(gè)進(jìn)入隊(duì)列的事務(wù)會(huì)成為leader,leader領(lǐng)導(dǎo)所在隊(duì)列的所有事務(wù),全權(quán)負(fù)責(zé)整隊(duì)的操作,完成后通知隊(duì)內(nèi)其他事務(wù)操作結(jié)束。
Flush 階段 (圖中第一個(gè)渡口)
- 首先獲取隊(duì)列中的事務(wù)組
- 將Redo log中prepare階段的數(shù)據(jù)刷盤(圖中Flush Redo log)
- 將binlog數(shù)據(jù)寫入文件,當(dāng)然此時(shí)只是寫入文件系統(tǒng)的緩沖,并不能保證數(shù)據(jù)庫(kù)崩潰時(shí)binlog不丟失 (圖中Write binlog)
- Flush階段隊(duì)列的作用是提供了Redo log的組提交
- 如果在這一步完成后數(shù)據(jù)庫(kù)崩潰,由于協(xié)調(diào)者binlog中不保證有該組事務(wù)的記錄,所以MySQL可能會(huì)在重啟后回滾該組事務(wù)
Sync 階段 (圖中第二個(gè)渡口)
- 這里為了增加一組事務(wù)中的事務(wù)數(shù)量,提高刷盤收益,MySQL使用兩個(gè)參數(shù)控制獲取隊(duì)列事務(wù)組的時(shí)機(jī):
binlog_group_commit_sync_delay=N:在等待N μs后,開(kāi)始事務(wù)刷盤(圖中Sync binlog)
binlog_group_commit_sync_no_delay_count=N:如果隊(duì)列中的事務(wù)數(shù)達(dá)到N個(gè),就忽視binlog_group_commit_sync_delay的設(shè)置,直接開(kāi)始刷盤(圖中Sync binlog)
- Sync階段隊(duì)列的作用是支持binlog的組提交
- 如果在這一步完成后數(shù)據(jù)庫(kù)崩潰,由于協(xié)調(diào)者binlog中已經(jīng)有了事務(wù)記錄,MySQL會(huì)在重啟后通過(guò)Flush 階段中Redo log刷盤的數(shù)據(jù)繼續(xù)進(jìn)行事務(wù)的提交
Commit 階段 (圖中第三個(gè)渡口)
- 首先獲取隊(duì)列中的事務(wù)組
- 依次將Redo log中已經(jīng)prepare的事務(wù)在引擎層提交(圖中InnoDB Commit)
- Commit階段不用刷盤,如上所述,F(xiàn)lush階段中的Redo log刷盤已經(jīng)足夠保證數(shù)據(jù)庫(kù)崩潰時(shí)的數(shù)據(jù)安全了
- Commit階段隊(duì)列的作用是承接Sync階段的事務(wù),完成最后的引擎提交,使得Sync可以盡早的處理下一組事務(wù),最大化組提交的效率
缺陷分析:
本文最后要討論的bug(可通過(guò)閱讀原文查看)就是來(lái)源于Sync 階段中的那個(gè)binlog參數(shù)binlog_group_commit_sync_delay,在MySQL 5.7.19中,如果該參數(shù)不為10的倍數(shù),則會(huì)導(dǎo)致事務(wù)在Sync 階段等待極大的時(shí)間,表現(xiàn)出來(lái)的現(xiàn)象就是執(zhí)行的sql長(zhǎng)時(shí)間無(wú)法返回。該bug已在MySQL 5.7.24和8.0.13被修復(fù)。
到此這篇關(guān)于MySQL組提交(group commit)的文章就介紹到這了,更多相關(guān)MySQL組提交內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Windows?Server?2019?MySQL數(shù)據(jù)庫(kù)的安裝與配置理論+遠(yuǎn)程連接篇
mysql是一款關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),由MySQL?AB公司開(kāi)發(fā),目前屬于Oracle旗下產(chǎn)品,MySQL是最流行的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)之一。MySQL也是一款開(kāi)源的SQL數(shù)據(jù)庫(kù)管理系統(tǒng),是眾多小型網(wǎng)站作為網(wǎng)站數(shù)據(jù)庫(kù)的首選數(shù)據(jù)庫(kù)2023-05-05
mysql查看binlog日志的實(shí)現(xiàn)方法
本文主要介紹了配置和查看MySQL 8.01的binlog日志,包括開(kāi)啟binlog日志、配置日志格式、查看日志位置和內(nèi)容等,具有一定的參考價(jià)值,感興趣的可以了解一下2024-11-11
mysql如何導(dǎo)出服務(wù)器內(nèi)所有的數(shù)據(jù)庫(kù)
這篇文章主要介紹了mysql如何導(dǎo)出服務(wù)器內(nèi)所有的數(shù)據(jù)庫(kù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
You must SET PASSWORD before execut
今天在MySql5.6操作時(shí)報(bào)錯(cuò):You must SET PASSWORD before executing this statement解決方法,需要的朋友可以參考下2013-06-06
在Windows系統(tǒng)上使用壓縮歸檔文件安裝MySQL的步驟
這篇文章主要介紹了在Windows系統(tǒng)上使用壓縮歸檔文件安裝MySQL的步驟,非常不錯(cuò),具有一定的參考借鑒加載,需要的朋友可以參考下2018-06-06
mysql自動(dòng)停止 Plugin FEDERATED is disabled 的完美解決方法
今天在配置服務(wù)器的時(shí)候,發(fā)現(xiàn)mysql的一個(gè)錯(cuò)誤提示在 本地計(jì)算機(jī) 無(wú)法啟動(dòng) MySQL 服務(wù)。錯(cuò)誤 1067: 進(jìn)程意外終止,其實(shí)原因很多這個(gè)不是導(dǎo)致進(jìn)程意外終止的最終原因,但可以解決2016-04-04
MySQL主從搭建(多主一從)的實(shí)現(xiàn)思路與步驟
通過(guò)MySQL主從配置,可以實(shí)現(xiàn)讀寫分離減輕數(shù)據(jù)庫(kù)壓力,最近正好遇到這個(gè)功能,所以這篇文章主要給大家介紹了關(guān)于MySQL主從搭建(多主一從)的實(shí)現(xiàn)思路與步驟,需要的朋友可以參考下2021-05-05

