眾所周知,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關注資料庫設計和配置問題,最後就是需要提高從節點的並發處理能力,由單線程回放改為多線程並行回放是一個比較好的方法,關鍵點在於如何在多線程恢復的前提下解決數據衝突和故障恢復位置點的確認問題。
在實例中有多個資料庫的情況下,可以開啟多個執行緒,每個執行緒對應一個資料庫。在該模式下從節點會啟動多個執行緒。執行緒分為兩類
Coordinator
和WorkThread
。
執行緒分工執行邏輯
#Coordinator
執行緒負責判斷事務是否可以並行執行,如果可以並行就把交易分發給WorkThread
執行緒執行,如果判斷不能執行,如DDL
,跨庫操作
等,就等待所有的worker執行緒執行完成之後,再由Coordinator
執行。
關鍵配置資訊
slave-parallel-type=DATABASE
#方案不足點
##這種並行複製的模式,只有在實例中有多個DB且DB的事務都相對繁忙的情況下才會有較高的並行度,但是日常維護中其實單一實例的的事務處理相對集中在一個DB上。大多數延遲情況都是基於熱點表的出現而觀察得出。如果能夠提供基於表的並行度是一個很好方法。MySQL5.7基於群組提交的平行複製群組提交說明
簡單來說就是在雙重1的設定下,交易提交後即刷盤的操作改為多個事務合併成一組事務再進行統一刷盤,這樣處理就降低了磁碟IO的壓力。詳細資料參考#組事務同時提交也意味著組內事務不存在衝突,故組內的事務在從節點上就可以並發執行,問題在於如何區分事務是否在同一組中的,於是在binlog中出現了兩個新的參數資訊老葉茶館
關於群組提交的說明推文
https://mp.weixin.qq.com/s/rcPkrutiLc93aTblEZ7sFg
last_committed 和
sequence_number
sequence_number
兩個參數信息,其中[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。达到期望的并行度后立即提交,尽量缩小等待延迟。
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
以上是MySQL Replication中並行複製怎麼實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!