[toc] 前言 操作系統使用 頁面緩存 來填補記憶體和磁碟訪問的差距 對磁碟文件的寫入會先寫入道頁面緩存中 由操作系統來 決定何時 將修改過的臟頁刷新到磁碟 確保修改已經持久化到磁碟,須調用 fsyn c或者 fdatasync 資料庫在事務提交過程中調用fsync將數據持久化到磁碟,才滿足 ACI ...
目錄
前言
- 操作系統使用頁面緩存來填補記憶體和磁碟訪問的差距
- 對磁碟文件的寫入會先寫入道頁面緩存中
- 由操作系統來決定何時將修改過的臟頁刷新到磁碟
- 確保修改已經持久化到磁碟,須調用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開啟多線程複製)
- 定時發車增加了事務提交的延遲,在高併發情況下,延遲有可能增加爭用從而減少吞吐量
定時發車有優點也有缺點,要更具業務負載持續優化來決定最佳設置
參考
binlog_group_commit_sync_delay
《Mariadb 原理與實現》
MySQL組提交