1. 程式人生 > 資料庫 >MySQL複製(三) - binlog組提交

MySQL複製(三) - binlog組提交

通過sync_binlog=1控制事件持久化到磁碟,每次事務提交時進行fsync操作,將消耗大量的磁碟IOPS,如何最大化的提高效能,降低fsync對事務高併發的影響呢?

一. 二階段提交

binlog是MySQL服務層產生的日誌,每個執行緒有獨立的快取,在事務提交時才寫入磁碟(fsync行為依賴sync_binlog設定),無法進行回滾,是邏輯的日誌,記錄行的改變或SQL語句。

redo日誌(WAL)是InnoDB儲存引擎產生的日誌,在事務的執行過程中一直會產生,所有執行緒共享記憶體快取(innodb_log_buffer_size),事務提交時會進行刷盤操作(fsync行為依賴innodb_flush_log_at_trx_commit設定),同時也會將沒提交的事務日誌順帶寫入磁碟,寫了redo的事務也能回滾。

binlog和redo是由不同的子系統產生的,兩個子系統怎麼協調,以保證binlog和redo的資料一致性呢?在分散式系統中,MySQL通過分散式事務(innodb_support_xa=1,8.0預設使用)來解決兩者的一致性問題,在事務提交時,redo先寫prepare 日誌,並做刷盤,然後寫binlog,並刷盤,寫成功後,再進行寫redo commit日誌。

二階段提交流程圖:

當prepare日誌寫成功,在寫binlog日誌時MySQL宕機,binlog沒寫成功(a位置),恢復時將回滾該事務,因binlog沒寫成功,如果事務進行提交的話,將會造成redo和binlog的不一致,引起主從資料不一致。

當prepare日誌和binlog都寫成功,如果發生宕機(b位置),在恢復時會通過Xid去binlog日誌查詢是否有對應事務的完整日誌,如binlog完整,儘管沒有redo commit日誌,也要進行事務提交,因binlog不能回滾,如果redo回滾,將會造成主從不一致,如沒有完整的binlog日誌將進行事務回滾。

二. binlog組提交

在MySQL 5.6之前,同時為了保障物理熱備份工具,其備份資料的一致性,二階段提交期間有prepare_commit_mutex鎖,造成多個事務的提交是序列的,同時redo group commit也失效,引起效能問題。

為了解決該效能問題,5.6通過BLGC(Binary Log Group Commit)的機制進行了優化,將binlog的寫分為三個階段:flush,sync,commit,每個階段由leader和follower組成,由leader控制follower的行為(follower不能成為leader),在commit階段由leader按順序呼叫儲存引擎進行事務的提交,同時也去掉prepare_commit_mutex鎖,提高了效能。

為了提高一次fsync操作更多的事務,提供了一些引數:

  1. binlog_max_flush_queue_time(5.7.9棄用),控制事務在flush佇列中等待的時間;

  2. binlog_group_commit_sync_delay,等待多少微秒後才進行fsync;

  3. binlog_group_commit_sync_no_delay_count,達到等待的事務數量後呼叫fsync操作;

以上控制組提交的引數需要結合業務情況進行配置,當多執行緒(併發量)寫時,效果更好。

全文完。

來源: