MySQL Replication--多线程复制MTS
多線程復制
多線程復制MTS(Mult-Threaded Slave Applier)指使用多個線程來并發應用二進制日志。
在MYSQL5.6版本中,多線程復制基于schema來實現,將多個數據庫下的事務按照數據庫拆分到多個線程上執行,保證數據庫級別的事務一致性。
在MYSQL5.7版本后,多線程復制基于主庫上并發信息來實現,主庫上并發提交的事務不存在事務沖突,在從庫上拆分到多個線程執行,保證實例級別的事務一致性。
設置和多線程復制類型和復制線程數:
##設置多線程復制類型和復制線程數: SET GLOBAL slave_parallel_type='DATABASE'; SET GLOBAL slave_parallel_type='LOGICAL_CLOCK'; SET GLOBAL slave_parallel_workers =8;## 查看多線程復制類型和復制線程數 SELECT @@slave_parallel_type,@@slave_parallel_workers;?
基于DATABASE的多線程復制
在MySQL 5.6中引入該特性,如果主庫上存在多個數據庫,每個數據庫的事務相互獨立于其他數據庫,因此只需要保證數據庫內部的事務運行順序和主庫上的運行順序一致,就可以保證主庫和從庫上的數據相同。
?
在MYSQL中開啟并行復制功能,SQL線程會變成coordinator線程,coordinator線程會對二進制日志的event進行判斷:
1、如果判斷事件可以被并行執行,那么選擇相應worker線程應用BINLOG事件
2、如果判斷事件不可以被并行執行,如DDL操作或跨schema事務,則等待所有worker線程執行完成后,再執行該BINLOG事件。
coordinator線程不僅分發BINLOG事件,也可以執行BINLOG事件。
當實例上數據庫數量較少或應用主要對某個數據庫進行讀寫,并行復制的性能可能會比單線程復制更差。
對于跨數據庫的事務或跨數據庫的外鍵,都會導致無法多線程并行執行。
?
基于DATABASE的多線程復制模式下執行位點問題:
1、MySQL使用Low-Water-Mark標記來最小已完成事件點,當發生宕機恢復時,根據Low-Water-Mark標記值來重放其后面的事件,而其中部分事件可能已被執行,重復執行可能會導致SQL線程異常或數據異常。
2、MySQL使用checkpint方式來推進APPLY主庫BINLOG的位置,使用SHOW SLAVE STATUS命令顯示的Exec_master_log_pos值是最近一次checkpint時的位點,而不是最后一個APPLY事務的值。
3、運行SQL_SLAVE_SKIP_COUNTER命令存在風險,可能會跳過其他事務。
4、對從庫進行備份獲取到的執行位點可能不是正確位點
5、當多個數據庫執行進度相差較大時,可以使用START SLAVE UNITL SQL_AFTER_MTS_GAPS語句來等待延遲較大的數據庫執行。
?
基于LOGICAL_CLOCK的多線程復制
在MySQL 5.7版本中引入,在主庫上的某個時間點上,所有完成excution處于prepare階段的事務都處于一個"相同的數據庫版本"上,這些事務之間不存在阻塞或者依賴,因此可以賦予一個相同的時間戳;擁有相同時間戳的事務可以在從庫上并行執行并且不會導致相互等待。如果事務間存在依賴,那么被阻塞的事務肯定處于Execution狀態而不會進入Prepare狀態。
?
如上圖中三個事務:
1、T1事務和T2事務的Commit階段有重合部分,T2事務和T3事務的Commit階段有重合部分,因此T1和T2可以在從庫上并發執行,T2和T3可以在從庫上并發執行。
2、T1事務和T3事務的Commit階段沒有有重合部分,無法判斷T3事務是否依賴于T1事務,因此T1和T3不能在從庫上并發執行。
Transactions with overlapping commit window can be executed in parallel;
?
在MYSQL 5.7版本的二進制日志中增加了last_committed和sequence_number,sequence_number表示當前語句所使用的編號,使用last_committed表示當前語句提交時的上一次組提交事務中最大的sequence_number。
相同last_committed的事件可以并行執行,無需考慮事件中的sequence_number。
?
#150520 14:23:11 server id 88 end_log_pos 259 CRC32 0x4ead9ad6 GTID last_committed=0 sequence_number=1 #150520 14:23:11 server id 88 end_log_pos 1483 CRC32 0xdf94bc85 GTID last_committed=0 sequence_number=2 #150520 14:23:11 server id 88 end_log_pos 2708 CRC32 0x0914697b GTID last_committed=0 sequence_number=3 #150520 14:23:11 server id 88 end_log_pos 3934 CRC32 0xd9cb4a43 GTID last_committed=0 sequence_number=4 #150520 14:23:11 server id 88 end_log_pos 5159 CRC32 0x06a6f531 GTID last_committed=0 sequence_number=5 #150520 14:23:11 server id 88 end_log_pos 6386 CRC32 0xd6cae930 GTID last_committed=0 sequence_number=6 #150520 14:23:11 server id 88 end_log_pos 7610 CRC32 0xa1ea531c GTID last_committed=6 sequence_number=7 #150520 14:23:11 server id 88 end_log_pos 8834 CRC32 0x96864e6b GTID last_committed=6 sequence_number=8 #150520 14:23:11 server id 88 end_log_pos 10057 CRC32 0x2de1ae55 GTID last_committed=6 sequence_number=9 #150520 14:23:11 server id 88 end_log_pos 11280 CRC32 0x5eb13091 GTID last_committed=6 sequence_number=10 #150520 14:23:11 server id 88 end_log_pos 12504 CRC32 0x16721011 GTID last_committed=6 sequence_number=11 #150520 14:23:11 server id 88 end_log_pos 13727 CRC32 0xe2210ab6 GTID last_committed=6 sequence_number=12 #150520 14:23:11 server id 88 end_log_pos 14952 CRC32 0xf41181d3 GTID last_committed=12 sequence_number=13?
?
多線程復制模式下的事務執行順序:
MySQL通過參數slave_preserve_commit_order可以控制Slave上的binlog提交順序和Master上的binlog的提交順序一樣,保證GTID的順序。該參數只能用于開啟了logical clock并且啟用了binlog的復制。即對于多線程復制,該參數用來保障事務在slave上執行的順序與relay log中的順序嚴格一致。開啟該參數可能會有一點的消耗,因為會讓slave的binlog提交產生等待。
比如兩個事務依次操作了2個DB:A和B,盡管事務A、B分別被worker X、Y線程接收,但是因為線程調度的問題,有可能導致A的執行時機落后于B。如果經常是“跨DB”操作,那么可以考慮使用此參數限定順序。當此參數開啟時,要求任何worker線程執行事務時,只有當前事務中之前的所有事務都執行后(被其他worker線程執行),才能執行和提交。(每個事務中,都記錄了當前GTID的privious GTID,只有privious GTID被提交后,當前GTID事務才能提交)。
建議在生產環境開啟該參數。
?
轉載于:https://www.cnblogs.com/gaogao67/p/11151621.html
總結
以上是生活随笔為你收集整理的MySQL Replication--多线程复制MTS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git push error. ! [r
- 下一篇: PHP性能调优---PHP-FPM配置及