[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開啟多線程復制)
定時發車增加了事務提交的延遲,在高並發情況下,延遲有可能增加爭用從而減少吞吐量
定時發車有優點也有缺點,要更具業務負載持續優化來決定最佳設置