MySQL Replication中的並行復制示例詳解
傳統單線程復制說明
眾所周知,MySQL在5.6版本之前,主從復制的從節點上有兩個線程,分別是I/O線程和SQL線程。
-
I/O線程負責接收二進制日志的Event寫入Relay Log。
-
SQL線程讀取Relay Log並在數據庫中進行回放。
以上方式偶爾會造成延遲,那麼可能造成主從節點延遲的情況有哪些?
-
1.主庫執行大事務(如:大表結構變更操作)。
-
2.主庫大批量變更(如:大量插入、更新、刪除操作)。
-
3.ROW同步模式下,主庫大表無主鍵頻繁更新。
-
4.數據庫參數配置不合理,從節點性能存在瓶頸(如:從節點事務日志設置過小,導致頻繁刷盤)。
-
5.網絡環境不穩定,從節點IO線程讀取binlog存在延遲、重連情況。
-
6.主從硬件配置差異,從節點的硬件資源使用達到上限。(比如:主節點SSD盤,從節點SAS盤)
可以對以上延遲原因做個大致分類。
-
1.硬件方面問題(包括磁盤IO、網絡IO等)
-
2.配置方面問題。
-
3.數據庫設計問題。
-
4.主庫大批量變更,從節點SQL單線程處理不夠及時。
總結
分析以上原因可以看出要想降低主從延遲,除瞭改善硬件方面條件之外,另外就是需要DBA關註數據庫設計和配置問題,最後就是需要提高從節點的並發處理能力,由單線程回放改為多線程並行回放是一個比較好的方法,關鍵點在於如何在多線程恢復的前提下解決數據沖突和故障恢復位置點的確認問題。
MySQL5.6基於庫級別的並行復制
在實例中有多個數據庫的情況下,可以開啟多個線程,每個線程對應一個數據庫。該模式下從節點會啟動多個線程。線程分為兩類
Coordinator
和WorkThread
。
-
線程分工執行邏輯
Coordinator
線程負責判斷事務是否可以並行執行,如果可以並行就把事務分發給WorkThread
線程執行,如果判斷不能執行,如DDL
,跨庫操作
等,就等待所有的worker線程執行完成之後,再由Coordinator
執行。
-
關鍵配置信息
slave-parallel-type=DATABASE
-
方案不足點
這種並行復制的模式,隻有在實例中有多個DB且DB的事務都相對繁忙的情況下才會有較高的並行度,但是日常維護中其實單個實例的的事務處理相對集中在一個DB上。通過觀察延遲可以發現基本上都是基於熱點表出現延遲的情況占大多數。如果能夠提供基於表的並行度是一個很好方法。
MySQL5.7基於組提交的並行復制
組提交說明
簡單來說就是在雙1的設置下,事務提交後即刷盤的操作改為多個事務合並成一組事務再進行統一刷盤,這樣處理就降低瞭磁盤IO的壓力。詳細資料參考
老葉茶館
關於組提交的說明推文https://mp.weixin.qq.com/s/rcPkrutiLc93aTblEZ7sFg
一組事務同時提交也就意味著組內事務不存在沖突,故組內的事務在從節點上就可以並發執行,問題在於如何區分事務是否在同一組中的,於是在binlog中出現瞭兩個新的參數信息last_committed
和 sequence_number
-
如何判斷事務在一個組內呢?
解析binlog可以發現裡面多瞭
last_committed
和sequence_number
兩個參數信息,其中last_committed
存在重復的情況。
-
sequence_number
# 這個值指的是事務提交的序號,單調遞增。 -
last_committed
# 這個值有兩層含義,1.相同值代表這些事務是在同一個組內,2.該值同時又是代表上一組事務的最大編號。
[root@mgr2 GreatSQL]# mysqlbinlog mysql-bin.0000002 | grep last_committed GTID last_committed=0 sequence_number=1 GTID last_committed=0 sequence_number=2 GTID last_committed=2 sequence_number=3 GTID last_committed=2 sequence_number=4 GTID last_committed=2 sequence_number=5 GTID last_committed=2 sequence_number=6 GTID last_committed=6 sequence_number=7 GTID last_committed=6 sequence_number=8
-
數據庫配置
slave-parallel-type=LOGICAL_CLOCK
-
方案不足點
基於組提交的同步有個不足點,就是當主節點的事務繁忙度較低的時候,導致時間段內組提交fsync刷盤的事務量較少,於是導致從庫回放的並行度並不高,甚至可能一組裡面隻有一個事務,這樣從節點的多線程就基本用不到,可以通過設置下面兩個參數,讓主節點延遲提交。
-
binlog_group_commit_sync_delay # 等待延遲提交的時間,binlog提交後等待一段時間再 fsync。讓每個 group 的事務更多,人為提高並行度。
-
binlog_group_commit_sync_no_delay_count # 待提交的最大事務數,如果等待時間沒到,而事務數達到瞭,就立即 fsync。達到期望的並行度後立即提交,盡量縮小等待延遲。
MySQL8.0基於writeset的並行復制
writeset 基於事務結果沖突進行判斷事務是否可以進行並行回放的方法,他由
binlog-transaction-dependency-tracking
參數進行控制,默認采用WRITESET
方法。
關鍵參數查看
Command-Line Format | –binlog-transaction-dependency-tracking=value |
---|---|
System Variable | binlog_transaction_dependency_tracking |
Scope | Global |
Dynamic | Yes |
SET_VAR Hint Applies | No |
Type | Enumeration |
Default Value | COMMIT_ORDER |
Valid Values | COMMIT_ORDER WRITESET WRITESET_SESSION |
參數配置項說明
-
COMMIT_ORDER
# 使用 5.7 Group commit 的方式決定事務依賴。 -
WRITESET
# 使用寫集合的方式決定事務依賴。 -
WRITESET_SESSION
# 使用寫集合,但是同一個session中的事務不會有相同的last_committed。
writeset 是一個HASH類型的數組,裡面記錄著事務的更新信息,通過
transaction_write_set_extraction
判斷當前事務更新的記錄與歷史事務更新的記錄是否存在沖突,判斷過後再采取對應處理方法。writeset儲存的最大存儲值由binlog-transaction-dependency-history-size
控制。
需要註意的是,當設置成
WRITESET
或WRITESET_SESSION
的時候,事務提交是無序狀態的,可以通過設置slave_preserve_commit_order=1
強制按順序提交。
-
binlog_transaction_dependency_history_size
設置保存在內存中的行哈希數的上限,用於緩存之前事務修改的行信息。一旦達到這個哈希數,就會清除歷史記錄。
Command-Line Format | –binlog-transaction-dependency-history-size=# |
---|---|
System Variable | binlog_transaction_dependency_history_size |
Scope | Global |
Dynamic | Yes |
SET_VAR Hint Applies | No |
Type | Integer |
Default Value | 25000 |
Minimum Value | 1 |
Minimum Value | 1000000 |
-
transaction_write_set_extraction
該模式支持三種算法,默認采用XXHASH64,當從節點配置writeset復制的時候,該配置不能配置為OFF。該參數已經在MySQL 8.0.26中被棄用,後續將會進行刪除。
Command-Line Format | –transaction-write-set-extraction[=value] |
---|---|
Deprecated | 8.0.26 |
System Variable | binlog_transaction_dependency_history_size |
Scope | Global, Session |
Dynamic | Yes |
SET_VAR Hint Applies | No |
Type | Enumeration |
Default Value | XXHASH64 |
Valid Values | OFF MURMUR32 XXHASH64 |
數據庫配置
slave_parallel_type = LOGICAL_CLOCK slave_parallel_workers = 8 binlog_transaction_dependency_tracking = WRITESET slave_preserve_commit_order = 1
引用資料:
-
阿裡內核月報:
http://mysql.taobao.org/monthly/2018/06/04/
-
官方文檔:
https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-log.html
到此這篇關於MySQL Replication之並行復制的文章就介紹到這瞭,更多相關MySQL 並行復制內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 一文詳解MySQL Binlog日志與主從復制
- MySQL之高可用架構詳解
- 解析MySQL binlog
- MySQL的binlog日志使用詳解
- Mysql主從三種復制模式(異步復制,半同步復制,組復制)