【MySQL】5.7增強(qiáng)半同步AFTER SYNC&AFTER COMMIT

????今天主要剖析一下MySQL 5.7增強(qiáng)半同步的AFTER SYNC和AFTER COMMIT的區(qū)別。
????如果我們生產(chǎn)庫(kù)對(duì)數(shù)據(jù)的一致性要求比較高,那么我們一般會(huì)開(kāi)啟了半同步復(fù)制,但在MySQL5.5/5.6里,會(huì)存在數(shù)據(jù)不一致的風(fēng)險(xiǎn)。比如有如下場(chǎng)景,客戶(hù)端提交了一個(gè)事務(wù),master把binlog發(fā)送給slave,在發(fā)送的期間,網(wǎng)絡(luò)出現(xiàn)波動(dòng),此時(shí)Binlog Dump線程發(fā)送就會(huì)卡住,要等待slave把binlog寫(xiě)到本地的relay-log里,然后給master一個(gè)反饋,等待的時(shí)間以rpl_semi_sync_master_timeout參數(shù)為準(zhǔn),默認(rèn)為10秒。在這等待的10秒鐘里,在其他會(huì)話(huà)里,查看剛才的事務(wù)是可以看見(jiàn)的,此時(shí)一旦master發(fā)生宕機(jī),由于binlog沒(méi)有發(fā)送給slave,前端app切到slave查看,就會(huì)發(fā)現(xiàn)剛才已提交的事務(wù)不見(jiàn)了。盜用兩張圖講解一下兩者的區(qū)別。

  • AFTER SYNC
    after sync是MySQL5.7官方新加的用以解決MySQL5.6半同步缺陷的選項(xiàng),也是官方推薦的方式。下面我結(jié)合圖來(lái)說(shuō)明一下AFTER SYNC是怎么回事。
    image

    ????實(shí)際上,客戶(hù)端發(fā)出commit請(qǐng)求后,在主庫(kù)上寫(xiě)入binlog并推送給slave,slave接收到binlog并寫(xiě)入relaylog,發(fā)送ACK確認(rèn)已經(jīng)接收binlog后,master在引擎層commit,客戶(hù)端接收commit完成,此時(shí)其他會(huì)話(huà)才可以看見(jiàn)已提交的數(shù)據(jù)。
    ????故障分析:假設(shè)master在接收ACK確認(rèn)時(shí)宕機(jī),因?yàn)樵谝鎸硬](méi)有提交,HA切換到從庫(kù),因?yàn)閎inlog已經(jīng)寫(xiě)入從庫(kù)的relaylog,因此不會(huì)造成數(shù)據(jù)丟失,個(gè)人認(rèn)為是目前比較完美的解決方式。
  • AFTER COMMIT
    image

    ????after commit是MySQL5.6半同步參數(shù),區(qū)別于after sync,after sync是在接收ack確認(rèn)以后主庫(kù)在引擎層做提交,而after commit是先在引擎層做提交后等待ACK確認(rèn)。因此,在寫(xiě)入數(shù)據(jù)后并且在從庫(kù)確認(rèn)之前,其他的客戶(hù)端可以看到在這一事務(wù)。
    ????故障分析:
    1.binlog 未發(fā)送到從庫(kù):
    ????事務(wù)B獲取到事務(wù)A提交的內(nèi)容, 此時(shí)宕機(jī)故障切換到slave,事務(wù)B獲取到的內(nèi)容卻丟失了。事務(wù)A commit沒(méi)有收到反饋信息(則需要業(yè)務(wù)判斷了)。
    2.binlog 已經(jīng)發(fā)送給從庫(kù) :
    ????事務(wù)B獲取到事務(wù)A提交的內(nèi)容,故障切換到salve ,B仍然獲取到A提交的內(nèi)容,沒(méi)毛病。事務(wù)A commit沒(méi)有收到反饋信息,若重新執(zhí)行該事務(wù),則相當(dāng)于執(zhí)行兩次A事務(wù)(則需要業(yè)務(wù)判斷了)。

dump thread過(guò)程分析:

  • mysql5.6版本之前:
    1. master dump thread 發(fā)送binlog events 給 slave 的IO thread,等待 slave 的ack反饋
    2. slave 接受binlog events 寫(xiě)入relay log ,返回 ack 消息給master dump thread
    3. master dump thread 收到ack消息,給session返回commit ok,然后繼續(xù)發(fā)送寫(xiě)一個(gè)事務(wù)的binlog。
  • mysql5.7之后新增ack線程:
    1. master dump thread 發(fā)送binlog events 給 slave 的IO thread,開(kāi)啟ack線程等待 slave 的ack反饋,dump 線程繼續(xù)向slaveIO thread發(fā)送下一個(gè)事務(wù)的binlog。
    2. slave 接受binlog events 寫(xiě)入relay log ,返回 ack 消息給master ack線程,然后給session返回commit ok。

過(guò)程總結(jié):

1.Master在收到slave的應(yīng)答后才Commit事務(wù)--after_sync(5.6上Master在commit后,才等待Slave的應(yīng)答--after commit).
因此在確認(rèn)事務(wù)復(fù)制到Slave上之前,并發(fā)的事務(wù)看不到當(dāng)前事務(wù)的數(shù)據(jù).當(dāng)Master出現(xiàn)故障時(shí),所有已經(jīng)提交的事務(wù)都復(fù)制到了Slave上.
2.缺省采用無(wú)數(shù)據(jù)丟失的應(yīng)答等待機(jī)制after_sync。用戶(hù)也可以選擇使用5.6的應(yīng)答等待機(jī)制after_commit

設(shè)置方法:

mysql> SET rpl_semi_sync_master_wait_point= AFTER_SYNC;

Master接收到N個(gè)slave的應(yīng)答后,才commit 事務(wù).
用戶(hù)可以設(shè)置應(yīng)答Slave的數(shù)量:

mysql> SET GLOBAL rpl_semi_sync_master_wait_for_slave_count= N;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容