1. 程式人生 > >MySQL無損復制(轉)

MySQL無損復制(轉)

oca 圖片 con 後來 ring 最好 完成後 復制 less

MySQL5.7新特性:lossless replication 無損復制

https://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html

MySQL的三種復制方式

  1. asynchronous 異步復制
  2. fully synchronous 全同步復制
  3. Semisynchronous 半同步復制

asynchronous replication

原理:在異步復制中,master寫數據到binlog且sync,slave request binlog後寫入relay-log並flush disk
優點:復制的性能最好

缺點:master掛掉後,slave可能會丟失事務
代表:MySQL原生的復制

技術分享圖片

fully synchronous replication

原理:在全同步復制中,master寫數據到binlog且sync,所有slave request binlog後寫入relay-log並flush disk,並且回放完日誌且commit
優點:數據不會丟失
缺點:會阻塞master session,性能太差,非常依賴網絡
代表:MySQL-Cluster

技術分享圖片

semisynchronous replication

  • 普通的半同步復制

原理: 在半同步復制中,master寫數據到binlog且sync,且commit,然後一直等待ACK。當至少一個slave request bilog後寫入到relay-log並flush disk,就返回ack(不需要回放完日誌)

優點:會有數據丟失風險(低)
缺點:會阻塞master session,性能差,非常依賴網絡,
代表:after commit, 原生的半同步
重點:由於master是在三段提交的最後commit階段完成後才等待,所以master的其他session是可以看到這個提交事務的,所以這時候master上的數據和slave不一致,master crash後,slave數據丟失

技術分享圖片

  • 增強版的半同步復制(lossless replication)

原理: 在半同步復制中,master寫數據到binlog且sync,然後一直等待ACK. 當至少一個slave request bilog後寫入到relay-log並flush disk,就返回ack(不需要回放完日誌)

優點:數據零丟失(前提是讓其一直是lossless replication),性能好
缺點:會阻塞master session,非常依賴網絡
代表:after sync, 原生的半同步
重點:由於master是在三段提交的第二階段sync binlog完成後才等待, 所以master的其他session是看不見這個提交事務的,所以這時候master上的數據和slave一致,master crash後,slave沒有丟失數據

技術分享圖片

重要參數

參數comment默認值推薦值是否動態
rpl_semi_sync_master_wait_for_slave_count 至少有N個slave接收到日誌 1 1 dynamic
rpl_semi_sync_master_wait_point 等待的point AFTER_SYNC AFTER_SYNC dynamic
rpl_semi_sync_master_timeout 切換復制的timeout 10000(10s) 1000(1s) dynamic
rpl_semi_sync_master_enabled 是否開啟半同步 OFF ON dynamic
rpl_semi_sync_slave_enabled 是否開啟半同步 OFF ON dynamic

如何開啟lossless replication

########semi sync replication settings########
plugin_dir=/usr/local/mysql/lib/plugin
plugin_load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
loose_rpl_semi_sync_master_enabled = 1
loose_rpl_semi_sync_slave_enabled = 1
loose_rpl_semi_sync_master_timeout = 1000

實踐是檢驗真理的唯一標準

如何檢驗上述after_sync,after_commit
如何檢驗上述原理的正確性

InnoDB commit : 三階段提交過程

A階段. wite prepare log -- 寫入Xid
B階段. write binlog
C階段. write commit log

測試點

master上當一個事務Waiting for semi-sync ACK from slave的時候,後來的事務是在A,B,C哪個階段卡住呢?

0,RC模式

1. semi-sync C階段等待

假設設置time-out=100000s,當事務一提交了一個大事務,在write commit log(C階段)時候等待,
那麽第二個事務在敲commit命令的時候,是卡在哪個階段呢?是卡在 wite prepare log(A階段)?還是write binlog(B階段)?還是write commit log(C階段)

測試:semi-sync vs  loss-less semi-sync

【semi-sync】 C階段等待
0, 開啟事務1,然後在slave上執行stop slave,制造timeout的情況,讓其阻塞。(Waiting for semi-sync ACK from slave)
1,在開啟一個事務2,事務2插入一條特殊記錄(XXXXX)。  (Waiting for semi-sync ACK from slave)
2,在開啟一個事務3。
2.1,測試案例:這個時候,kill -9 mysqld,造成人為的mysql crash
3,假設卡在A階段,那麽事務3,肯定是看不到事務1,2寫入的記錄(XXXXX),且重啟mysql後,事務2不會提交。
4,假設卡在C階段,那麽事務3,肯定是可以看見事務1,2寫入的記錄(XXXXX)。

經過測試:
1,是卡在C階段,也就是說事務3是可以看見事務1,事務2的。
2,MySQL crash重啟後,事務1,事務2的dml都已經提交成功,說明不是卡在A階段

【loss-less semi-sync】B階段等待

0, 開啟事務1,然後在slave上執行stop slave,制造timeout的情況,讓其阻塞。(Waiting for semi-sync ACK from slave)
1,在開啟一個事務2,事務2插入一條特殊記錄(XXXXX)。(Waiting for semi-sync ACK from slave)
2,在開啟一個事務3
3,假設卡在A階段,那麽事務3,肯定是看不到事務1,2寫入的記錄(XXXXX),且重啟mysql後,事務2不會提交。。
4,假設卡在B階段,那麽事務3,肯定是可以看見事務1,2寫入的記錄(XXXXX),且重啟mysql後,事務1,2都會提交。。
5, 假設卡在C階段,那麽事務3,肯定是可以看見事務3寫入的記錄(XXXXX)。

經過測試:
1,是卡在B階段,也就是說事務3,既看不見事務1的提交內容,也看不見事務2的提交內容,且重啟mysql後,事務1,2都已經提交。。
2,MySQL crash重啟後,事務1,事務2的dml都已經提交成功,說明不是卡在A階段。

性能

semi-sync vs lossless semi-sync 的性能對比

根據以上的測試,可以得知,lossless只卡在B階段,普通的semi-sync是卡在C階段。
lossless的性能遠遠好於普通的semi-sync,即(after_sync 優於 after_commit)
因為lossless 卡在B階段的時候可以堆積事務,可以在C階段進行group commit。
普通的semi-sync,卡在C階段,事務都已經commit了,並沒有堆積的過程。

CAP理論

一致性【C】
可用性【A】
分區容忍性【P】
理論:CAP 三者不可兼得,必須要犧牲一個

分區,是一定存在的,不是你想不要就不要的。所以,這裏只剩下兩種組合

  • CP 犧牲可用性

這種做法,就是保留強一致性,犧牲可用性
案例:可以將rpl_semi_sync_master_timeout設置成一個無限大的值,比如:100天,那麽master和slave就強一致了,但是可用性就大打折扣

  • AP 犧牲一致性

這種做法,就是保留高可用性,犧牲一致性
案例:比如原生的異步復制就是這樣咯。可以快速做到切換,但是一致性就沒有保障

MySQL無損復制(轉)