MySQL 組提交(group commit)


[toc]


前言

  • 操作系統使用頁面緩存來填補內存和磁盤訪問的差距
  • 對磁盤文件的寫入會先寫入道頁面緩存中
  • 由操作系統來決定何時將修改過的臟頁刷新到磁盤
  • 確保修改已經持久化到磁盤,須調用fsync或者fdatasync
  • 數據庫在事務提交過程中調用fsync將數據持久化到磁盤,才滿足ACID中的D(持久化)
  • fsync是昂貴的操作,對於普通磁盤,每秒能完成幾百次fsync
  • MySQL中使用了兩階段提交協議,為了滿足D(持久化) ,一次事務提交最多會導致3次fsync
  • 提交的事務在存儲引擎內部(redo log)中准備好,一次fsync;事務寫入到binlog中並刷盤持久化,一次fsync;事務在存儲引擎內部提交,一次fsync(可以省略,存儲引擎准備好的事務可以通過binlog來恢復)

改進

  • 為了提高單位時間內的事務提交數,必須減少事務提交過程中的fsync調用次數
  • MySQL 從5.6版本開始引入group commit技術(MariaDB 5.3版本引入)
  • 基本思想是多個並發提交的事務共用一次fsync操作來實現持久化 group commit An InnoDB optimization that performs some low-level I/O operations (log write) once for a set of commit operations, rather than flushing and syncing separately for each commit

原理

  • 多個並發需要提交的事務共享一次fsync操作來進行數據的持久化
  • 將fsync操作的開銷平攤到多個並發的事務上去
  • group commit 不是在任何時候都能發揮作用,要有足夠多並發的需要提交的事務

實現

  • 多個並發提交的事務在寫redo log或binlog前會被加入到一個隊列
  • 隊列頭部的事務所在的線程稱為leader線程,其它事務所在的線程稱為follower線程
  • leader線程負責為隊列中所有的事務進行寫binlog操作,此時,所有的follower線程處於等待狀態
  • 然后leader線程調用一次fsync操作,將binlog持久化
  • 最后通知follower線程可以繼續往下執行

參數

binlog_group_commit_sync_delay=N

定時發車,在等待N 微秒后,進行binlog刷盤操作

binlog_group_commit_sync_no_delay_count=N

人滿發車,達到最大事務等待數量,開始binlog刷盤,忽略定時發車

注意

  • 當binlog_group_commit_sync_delay=0時,binlog_group_commit_sync_no_delay_count參數設置無效,即沒有定時發車情況下,人滿發車也就沒有了~_~

  • 當sync_binlog=0或sync_binlog=1,在刷盤前,對每個binlog應用定時發車

  • 當sync_binlog=N(N>1),在每N個binlog后應用定時發車

  • 設置了定時發車增加了並發提交事務的數量,從而增加slave並行apply的速度(slave開啟多線程復制)

  • 定時發車增加了事務提交的延遲,在高並發情況下,延遲有可能增加爭用從而減少吞吐量

  • 定時發車有優點也有缺點,要更具業務負載持續優化來決定最佳設置

0dc72bd451ecc4bf914e1cefaf9c779f.gif

參考 binlog_group_commit_sync_delay 《Mariadb 原理與實現》 MySQL組提交


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM