MySQL并行復(fù)制的深入淺出
1.DBA都應(yīng)該知道,MySQL的復(fù)制是基于binlog的。 2.MySQL復(fù)制包括兩部分,IO線程 和 SQL線程。 3.IO線程主要是用于拉取接收Master傳遞過來的binlog,并將其寫入到relay log 4.SQL線程主要負(fù)責(zé)解析relay log,并應(yīng)用到slave中 5.不管怎么說,IO和SQL線程都是單線程的,然后master卻是多線程的,所以難免會有延遲,為了解決這個問題,多線程應(yīng)運(yùn)而生了。 6.IO多線程? 6.1 IO沒必要多線程,因為IO線程并不是瓶頸啊7.SQL多線程?7.1 沒錯,目前最新的5.6,5.7,8.0 都是在SQL線程上實現(xiàn)了多線程,來提升slave的并發(fā)度接下來,我們就來一窺MySQL在并行復(fù)制上的努力和成果吧 二、重點
是否能夠并行,關(guān)鍵在于多事務(wù)之間是否有鎖沖突,這是關(guān)鍵。 下面的并行復(fù)制原理就是在看如何讓避免鎖沖突
三、MySQL5.6 基于schema的并行復(fù)制slave-parallel-type=DATABASE(不同庫的事務(wù),沒有鎖沖突)
之前說過,并行復(fù)制的目的就是要讓slave盡可能的多線程跑起來,當(dāng)然基于庫級別的多線程也是一種方式(不同庫的事務(wù),沒有鎖沖突)
先說說優(yōu)點: 實現(xiàn)相對來說簡單,對用戶來說使用起來也簡單
再說說缺點: 由于是基于庫的,那么并行的粒度非常粗,現(xiàn)在很多公司的架構(gòu)是一庫一實例,針對這樣的架構(gòu),5.6的并行復(fù)制無能為力。當(dāng)然還有就是主從事務(wù)的先后順序,對于5.6也是個大問題
話不多說,來張圖好了

slave-parallel-type=LOGICAL_CLOCK : Commit-Parent-Based模式(同一組的事務(wù)[last-commit相同],沒有鎖沖突. 同一組,肯定沒有沖突,否則沒辦法成為同一組)
slave-parallel-type=LOGICAL_CLOCK : Lock-Based模式(即便不是同一組的事務(wù),只要事務(wù)之間沒有鎖沖突[prepare階段],就可以并發(fā)。 不在同一組,只要N個事務(wù)prepare階段可以重疊,說明沒有鎖沖突)
group commit,之前的文章有詳細(xì)描述,這里不多解釋。MySQL5.7在組提交的時候,還為每一組的事務(wù)打上了標(biāo)記,現(xiàn)在想想就是為了方便進(jìn)行MTS吧。
我們先看一組binlog
last_committed=0 sequence_number=1last_committed=1 sequence_number=2last_committed=2 sequence_number=3last_committed=3 sequence_number=4last_committed=4 sequence_number=5last_committed=4 sequence_number=6last_committed=4 sequence_number=7last_committed=6 sequence_number=8last_committed=6 sequence_number=9last_committed=9 sequence_number=10 4.1 Commit-Parent-Based模式


基于主鍵的沖突檢測(binlog_transaction_depandency_tracking = COMMIT_ORDERE|WRITESET|WRITESET_SESSION, 修改的row的主鍵或非空唯一鍵沒有沖突,即可并行)
5.7.22 也支持了 write-set 機(jī)制
事務(wù)依賴關(guān)系:binlog_transaction_depandency_tracking = COMMIT_ORDERE|WRITESET|WRITESET_SESSIONCOMMIT_ORDERE: 繼續(xù)基于組提交方式WRITESET: 基于寫集合決定事務(wù)依賴WRITESET_SESSION: 基于寫集合,但是同一個session中的事務(wù)不會有相同的last_committed 事務(wù)檢測算法:transaction_write_set_extraction = OFF| XXHASH64 | MURMUR32
MySQL會有一個變量來存儲已經(jīng)提交的事務(wù)HASH值,所有已經(jīng)提交的事務(wù)所修改的主鍵(或唯一鍵)的值經(jīng)過hash后都會與那個變量的集合進(jìn)行對比,來判斷改行是否與其沖突,并以此來確定依賴關(guān)系
這里說的變量,可以通過這個設(shè)置大小: binlog_transaction_dependency_history_size
這樣的粒度,就到了 row級別了,此時并行的粒度更加精細(xì),并行的速度會更快,某些情況下,說slave的并行度超越master也不為過(master是單線程的寫,slave也可以并行回放)
六、如何讓slave的并行復(fù)制和master的事務(wù)執(zhí)行的順序一致呢5.7.19 之后,可以通過設(shè)置 slave_preserve_commit_order = 1
官方解釋: For multithreaded slaves, enabling this variable ensures that transactions are externalized on the slave in the same order as they appear in the slave’s relay log. Setting this variable has no effect on slaves for which multithreading is not enabled. All replication threads (for all replication channels if you are using multiple replication channels) must be stopped before changing this variable. --log-bin and --log-slave-updates must be enabled on the slave.In addition --slave-parallel-type must be set to LOGICAL_CLOCK.Once a multithreaded slave has been started, transactions can begin to execute in parallel. With slave_preserve_commit_order enabled, the executing thread waits until all previous transactions are committed before committing. While the slave thread is waiting for other workers to commit their transactions it reports its status as Waiting for preceding transaction to commit.大致實現(xiàn)原理就是:excecution階段可以并行執(zhí)行,binlog flush的時候,按順序進(jìn)行。 引擎層提交的時候,根據(jù)binlog_order_commit也是排隊順序完成 換句話說,如果設(shè)置了這個參數(shù),master是怎么并行的,slave就怎么辦并行
來自:http://keithlan.github.io/2018/07/31/mysql_mts_detail/
相關(guān)文章:
1. Access數(shù)據(jù)庫安全的幾個問題2. Windwos下MySQL 64位壓縮包的安裝方法學(xué)習(xí)記錄3. mysql啟動時報錯 ERROR! Manager of pid-file quit without4. mysql-bin.000001文件的來源及處理方法5. Windows下在DOS用mysql命令行導(dǎo)入.sql文件6. mysql命令行客戶端結(jié)果分頁瀏覽7. MySQL全文搜索之布爾搜索8. 如何實現(xiàn)MySQL數(shù)據(jù)庫的備份與恢復(fù)9. 什么是Access數(shù)據(jù)庫10. MySQL中 concat函數(shù)的使用

網(wǎng)公網(wǎng)安備