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