這篇文章將為大家詳細(xì)講解有關(guān)MySQL中并行復(fù)制亂序提交引起的同步異常如何處理,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
成都創(chuàng)新互聯(lián)公司是專業(yè)的威縣網(wǎng)站建設(shè)公司,威縣接單;提供網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行威縣網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!Slave在開啟并行復(fù)制后, 默認(rèn)會(huì)亂序提交事務(wù), 可能會(huì)引起同步中斷;
Slave端表現(xiàn)為同步的SQL線程拋出異常, 為主鍵重復(fù), 修改的數(shù)據(jù)行不存在等;
GTID信息類似于: 9a2a50aa-5504-11e7-9e59-246e965d93f4:1-1371939844:1371939846
其中1371939845為報(bào)錯(cuò)的事務(wù), 直觀上看, Slave端先提交了1371939846事務(wù);
MySQLversion>=5.7.5
slave_preserve_commit_order:OFF(default)->ON
注:binlog_order_commits=ON(default)
參考官方的WL#6314和WL#7165, 這里對(duì)原文內(nèi)容進(jìn)行簡(jiǎn)單的歸納, 有興趣的可以看看原文的High Level Architecture;
WL#6314 : https://dev.mysql.com/worklog/task/?id=6314
WL#7165 : https://dev.mysql.com/worklog/task/?id=7165
注: 英文原文中的commit-parent transaction, sequence number指的就是binlog中的last_commited和sequence_number; 即簡(jiǎn)單翻譯中的”邏輯時(shí)間戳標(biāo)記”
當(dāng)事務(wù)進(jìn)入prepare階段(組提交流程的某一個(gè)階段)時(shí), 這些事務(wù)都會(huì)獲得一個(gè)邏輯時(shí)間戳的標(biāo)記, 用來(lái)標(biāo)記最新提交的事務(wù)是哪個(gè);
在master端, 有關(guān)流程如下:
在prepare階段, 從commit_clock中獲取時(shí)間戳并存儲(chǔ)下來(lái), 用來(lái)標(biāo)記最新提交的事務(wù);
在commit階段(事務(wù)已經(jīng)寫入binlog, 但是在引擎層提交前), 對(duì)commit_clock執(zhí)行步進(jìn)操作;
在Slave端, 有關(guān)流程如下:
coordinate線程會(huì)讀取relaylog的event, 如果這些event都有相同的邏輯時(shí)間戳(last_commited), 那么這些event就可以由worker并行執(zhí)行;
舉例: 下圖代表各個(gè)事務(wù)的執(zhí)行順序與時(shí)間線, 其中P代表單個(gè)事務(wù)的prepare階段, 在這個(gè)階段會(huì)獲取到commit_clock的時(shí)間戳, C代表這個(gè)事務(wù)的寫binlog的階段, 在這里會(huì)對(duì)commit_clock進(jìn)行步進(jìn)操作;
如上圖所示, Trx1, Trx2, Trx3的P階段獲取到的都是同一個(gè)last_commited值(比如說(shuō)是1), 因此這三個(gè)事務(wù)可以在Slave端并行執(zhí)行; 同理, Trx4不能和< Trx1, Trx2, Trx3 > 一起并行回放, 因?yàn)門rx4的P階段, 獲取到的last_commited值是Trx1執(zhí)行完步進(jìn)以后的值(步進(jìn)之后變成了2);
按照WL#6314的邏輯, Slave端可以發(fā)現(xiàn)這七個(gè)事務(wù)分成了四個(gè)事務(wù)組, 分別是< Trx1, Trx2, Trx3 >, < Trx4 >, < Trx5, Trx6 >, < Trx7 >;
但是需要注意的是, 對(duì)于不同的事務(wù)組, < Trx4 > 和 < Trx5, Trx6 > 是能并發(fā)執(zhí)行的, 因?yàn)閺臅r(shí)間線上看, < Trx4 > 和 < Trx5, Trx6 > 的prepare階段在時(shí)間線上是有重疊的, 這也就意味著這兩組事務(wù)并不存在鎖的沖突, 那么就可以在Slave并行執(zhí)行;
改進(jìn)后的并行復(fù)制使用鎖來(lái)判斷是否可以進(jìn)行并發(fā);
基本邏輯如下:
L代表鎖階段開始, C代表鎖階段結(jié)束;
A中的Trx1和Trx2由于鎖階段存在重合, 也沒有發(fā)生沖突, 說(shuō)明Trx1和Trx2是可以并行執(zhí)行的, 但是B不行, 因?yàn)門rx1和Trx2的鎖階段沒有重合, 所以無(wú)法確認(rèn)是不是可以并行執(zhí)行(不做額外的判斷, 直接當(dāng)做不可并行處理, 節(jié)約性能開銷);
關(guān)于鎖階段的判斷, WL中明確表示沒有進(jìn)行鎖分析, 而是直接把事務(wù)提交的一些階段作為加鎖與釋放鎖的時(shí)間點(diǎn)(從事務(wù)提交的階段來(lái)看, 也沒什么問(wèn)題);
假設(shè)在進(jìn)行存儲(chǔ)引擎層的提交之前, 所有的鎖都已已經(jīng)釋放(鎖階段結(jié)束的時(shí)間點(diǎn));
假設(shè)在prepare階段開始的時(shí)候, 所有需要的鎖已經(jīng)全部獲取到(鎖階段開始的時(shí)間點(diǎn));
在MySQL的binlog中, L所指的標(biāo)記就是last_commited, C所指的標(biāo)記就是sequence_number;
關(guān)于last_commited和sequence_number, WL#7165有做如下描述
在事務(wù)進(jìn)入flush階段前, 會(huì)步進(jìn)transaction.sequence_number的值 –> 顯示為sequence_number
在事務(wù)進(jìn)入引擎層提交之前, 會(huì)修改 global.max_committed_transaction的值
= max(global.max_committed_timestamp, transaction.sequence_number)
= transaction.sequence_number (如果binlog_order_commits使用默認(rèn)值ON)
因此, Slave端在決定SQL是否可以并發(fā)執(zhí)行時(shí), 參考如下原則:
-----------------------------------------------------------------------------------------------------------
Slave can execute a transactionifthe smallest sequence_number
among all executing transactions is greater than transaction.last_committed.
-----------------------------------------------------------------------------------------------------------
偽代碼會(huì)更直觀一些:
-----------------------------------------------------------------------------------------------------------
Slave logic:
-before scheduler pushes the transaction for execution : wait until transaction_sequence[0].sequence_number>transaction.last_committed
-----------------------------------------------------------------------------------------------------------
所以使用基于鎖的并行度優(yōu)化后, 確實(shí)可以讓W(xué)L#6314的< Trx4 > 和 < Trx5, Trx6 > 并發(fā)執(zhí)行;
Slave上報(bào)錯(cuò)的事務(wù)為1371939845, binlog內(nèi)容如下, 事務(wù)缺少1371939845;
Master上的事務(wù)序列如下:
參考WL#6314的格式, 根據(jù)Master的事務(wù)序列繪制事務(wù)序列圖, GTID, last_commited, sequence_number均使用最后兩位數(shù)作為標(biāo)記;
由于Slave是亂序提交的, 所以這些事務(wù)在Slave的binlog中并非嚴(yán)格按照GTID遞增的順序出現(xiàn)
根據(jù)WL#7165的描述, 可以得出: 在Slave上, 當(dāng)Trx41執(zhí)行完畢之后, Slave認(rèn)為, Trx46與Trx47已經(jīng)可以由coordinate進(jìn)行調(diào)度, 與< Trx42, Trx43, Trx44, Trx45 > 并行執(zhí)行了, 但是Trx45與Trx46, Trx47 存在業(yè)務(wù)上的先后順序(且確實(shí)存在鎖沖突), 所以先執(zhí)行的Trx46刪除了Trx45需要的數(shù)據(jù), 導(dǎo)致同步中斷;
PS: 既然Trx45和Trx46有鎖沖突, 為什么Trx46會(huì)拿到84作為last_commited, 而不是88?
參考WL#7165的偽代碼,
-----------------------------------------------------------------------------------------------------------
When@@global.binlog_order_commitsistrue,inprinciple we could reduce
the max
to an assignment:
global.max_committed_transaction=transaction.sequence_number
-----------------------------------------------------------------------------------------------------------
MySQL-5.7.21的源代碼:
MYSQL_BIN_LOG::ordered_commit-->
process_commit_stage_queue-->
update_max_committed
-----------------------------------------------------------------------------------------------------------
因此推測(cè)主庫(kù)當(dāng)時(shí)候是如下場(chǎng)景:<Trx35~Trx45>作為一個(gè)事務(wù)組,進(jìn)入到了存儲(chǔ)引擎的commit階段前,會(huì)遞增sequence_number,而不是一次到位的全部加上;
所以Trx46進(jìn)入prepare階段時(shí),剛好是Trx41完成了commit階段,所以拿到的是84,而不是88;雖然官方描述中,認(rèn)為會(huì)達(dá)到最終一致的狀態(tài),但是同步過(guò)程中會(huì)存在短暫的不一致現(xiàn)象,這種現(xiàn)象被描述為"GAP";
關(guān)于“MySQL中并行復(fù)制亂序提交引起的同步異常如何處理”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
本文標(biāo)題:MySQL中并行復(fù)制亂序提交引起的同步異常如何處理-創(chuàng)新互聯(lián)
本文來(lái)源:http://aaarwkj.com/article38/ccoisp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、動(dòng)態(tài)網(wǎng)站、移動(dòng)網(wǎng)站建設(shè)、虛擬主機(jī)、網(wǎng)站導(dǎo)航、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容