天天看點

[圖解MySQL]MySQL組送出(group commit)

[圖解MySQL]MySQL組送出(group commit)

前提:

以下讨論的前提 是設定MySQL的crash safe相關參數為雙1:

sync_binlog=1

innodb_flush_log_at_trx_commit=1

背景說明:

WAL機制 (Write Ahead Log)定義:

WAL指的是對資料檔案進行修改前,必須将修改先記錄日志。MySQL為了保證ACID中的一緻性和持久性,使用了WAL。

Redo log的作用:

Redo log就是一種WAL的應用。當資料庫忽然掉電,再重新啟動時,MySQL可以通過Redo log還原資料。也就是說,每次事務送出時,不用同步重新整理磁盤資料檔案,隻需要同步重新整理Redo log就足夠了。相比寫資料檔案時的随機IO,寫Redo log時的順序IO能夠提高事務送出速度。

組送出的作用:

在沒有開啟binlog時

Redo log的刷盤操作将會是最終影響MySQL TPS的瓶頸所在。為了緩解這一問題,MySQL使用了組送出,将多個刷盤操作合并成一個,如果說10個事務依次排隊刷盤的時間成本是10,那麼将這10個事務一次性一起刷盤的時間成本則近似于1。

當開啟binlog時

為了保證Redo log和binlog的資料一緻性,MySQL使用了二階段送出,由binlog作為事務的協調者。而 引入二階段送出 使得binlog又成為了性能瓶頸,先前的Redo log 組送出 也成了擺設。為了再次緩解這一問題,MySQL增加了binlog的組送出,目的同樣是将binlog的多個刷盤操作合并成一個,結合Redo log本身已經實作的 組送出,分為三個階段(Flush 階段、Sync 階段、Commit 階段)完成binlog 組送出,最大化每次刷盤的收益,弱化磁盤瓶頸,提高性能。

圖解:

下圖我們假借“渡口運輸”的例子來看看binlog 組送出三個階段的流程:

[圖解MySQL]MySQL組送出(group commit)

在MySQL中每個階段都有一個隊列,每個隊列都有一把鎖保護,第一個進入隊列的事務會成為leader,leader上司所在隊列的所有事務,全權負責整隊的操作,完成後通知隊内其他事務操作結束。

Flush 階段 (圖中第一個渡口)

首先擷取隊列中的事務組

将Redo log中prepare階段的資料刷盤(圖中Flush Redo log)

将binlog資料寫入檔案,當然此時隻是寫入檔案系統的緩沖,并不能保證資料庫崩潰時binlog不丢失 (圖中Write binlog)

Flush階段隊列的作用是提供了Redo log的組送出

如果在這一步完成後資料庫崩潰,由于協調者binlog中不保證有該組事務的記錄,是以MySQL可能會在重新開機後復原該組事務

Sync 階段 (圖中第二個渡口)

這裡為了增加一組事務中的事務數量,提高刷盤收益,MySQL使用兩個參數控制擷取隊列事務組的時機:

binlog_group_commit_sync_delay=N:在等待N μs後,開始事務刷盤(圖中Sync binlog)

binlog_group_commit_sync_no_delay_count=N:如果隊列中的事務數達到N個,就忽視binlog_group_commit_sync_delay的設定,直接開始刷盤(圖中Sync binlog)

Sync階段隊列的作用是支援binlog的組送出

如果在這一步完成後資料庫崩潰,由于協調者binlog中已經有了事務記錄,MySQL會在重新開機後通過Flush 階段中Redo log刷盤的資料繼續進行事務的送出

Commit 階段 (圖中第三個渡口)

依次将Redo log中已經prepare的事務在引擎層送出(圖中InnoDB Commit)

Commit階段不用刷盤,如上所述,Flush階段中的Redo log刷盤已經足夠保證資料庫崩潰時的資料安全了

Commit階段隊列的作用是承接Sync階段的事務,完成最後的引擎送出,使得Sync可以盡早的處理下一組事務,最大化組送出的效率

缺陷分析:

本文最後要讨論的bug(可通過閱讀原文檢視)就是來源于Sync 階段中的那個binlog參數binlog_group_commit_sync_delay,在MySQL 5.7.19中,如果該參數不為10的倍數,則會導緻事務在Sync 階段等待極大的時間,表現出來的現象就是執行的sql長時間無法傳回。該bug已在MySQL 5.7.24和8.0.13被修複。

原文釋出時間為:2018-07-23

本文作者:黃炎 王悅 周海鳴

本文來自雲栖社群合作夥伴“

老葉茶館

”,了解相關資訊可以關注“