1. 程式人生 > 資料庫 >記錄mysql半同步複製,組提交相關

記錄mysql半同步複製,組提交相關

非同步複製(Asynchronous replication)
MySQL預設的複製即是非同步的,主庫在執行完客戶端提交的事務後會立即將結果返給給客戶端,並不關心從庫是否已經接收並處理,這樣就會有一個問題,主如果crash掉了,此時主上已經提交的事務可能並沒有傳到從上,如果此時,強行將從提升為主,可能導致新主上的資料不完整。

全同步複製(Fully synchronous replication)
指當主庫執行完一個事務,所有的從庫都執行了該事務才返回給客戶端。因為需要等待所有從庫執行完該事務才能返回,所以全同步複製的效能必然會收到嚴重的影響。

半同步複製(Semisynchronous replication)

介於非同步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於非同步複製,半同步複製提高了資料的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步複製最好在低延時的網路中使用。

半同步複製的安裝部署
要想使用半同步複製,必須滿足以下幾個條件:

  1. MySQL 5.5及以上版本
  2. 變數have_dynamic_loading為YES
  3. 非同步複製已經存在

半同步複製問題:
AFTER_SYNC(無損複製)
如果你的生產庫開啟了半同步複製,那麼對資料的一致性會要求較高,但在MySQL5.5/5.6裡,會存在資料不一致的風險。有這麼一個場景,客戶端提交了一個事務,master把binlog傳送給slave,在傳送的期間,網路出現波動,此時Binlog Dump執行緒傳送就會卡住,要等待slave把binlog寫到本地的relay-log裡,然後給master一個反饋,等待的時間以rpl_semi_sync_master_timeout引數為準,預設為10秒。在這等待的10秒鐘裡,在其他會話裡,檢視剛才的事務是可以看見的,此時一旦master發生宕機,由於binlog沒有傳送給slave,前端app切到slave檢視,就會發現剛才已提交的事務不見了。

為了解決這種問題,MySQL5.7 改善了半同步複製這個缺陷。通過rpl_semi_sync_master_wait_point這個引數加以控制,預設是AFTER_SYNC,官方推薦用這個,它的工作原理是:master把binlog傳送給slave,只有在slave把binlog寫到本地的relay-log裡,才提交到儲存引擎層,然後把請求返回給客戶端,客戶端才可以看見剛才提交的事務。如果slave未儲存到本地的relay-log裡,客戶端是看不見剛才的事務的,這樣就不會造成上述那個場景發生。另一個值是AFTER_COMMIT,這個值是採用老式的MySQL5.5/5.6半同步複製工作。

無損複製:

無損複製時機

普通的半同步複製
原理: 在半同步複製中,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沒有丟失資料

並行複製:
在早期的 MySQL 中,slave 的 SQL 執行緒是單執行緒。master 可以支援 SQL 語句的並 行執行,配置了多少的最大連線數就是最多同時多少個 SQL 並行執行。
而 slave 的 SQL 卻只能單執行緒排隊執行,在主庫併發量很大的情況下,同步資料肯 定會出現延遲

mysql並行複製
● 社群版5.6中新增
● 並行是指從庫多執行緒apply binlog
● 庫級別並行應用binlog,同一個庫資料更改還是序列的(5.7版並行複製基於事務組)

組提交:
組複製(group commit):通過對事務進行分組,優化減少了生成二進位制日誌所需的運算元。當事務同時提交時,它們將在單個操作中寫入到二進位制日誌中。如果事務能同時提交成功,那麼它們就不會共享任何鎖,這意味著它們沒有衝突,因此可以在Slave上並行執行。所以通過在主機上的二進位制日誌中新增組提交資訊,這些Slave可以並行地安全地執行事務。
MySQL 5.7的並行複製基於一個前提,即所有已經處於prepare階段的事務,都是可以並行提交的。這些當然也可以在從庫中並行提交,因為處理這個階段的事務,都是沒有衝突的,該獲取的資源都已經獲取了。反過來說,如果有衝突,則後來的會等已經獲取資源的事務完成之後才能繼續,故而不會進入prepare階段。這是一種新的並行複製思路,完全擺脫了原來一直致力於為了防止衝突而做的分發演算法,等待策略等複雜的而又效率底下的工作。MySQL 5.7並行複製的思想一言以蔽之:一個組提交(group commit)的事務都是可以並行回放,因為這些事務都已進入到事務的prepare階段,則說明事務之間沒有任何衝突(否則就不可能提交)。
支援並行複製的GTID
那麼如何知道事務是否在同一組中,又是一個問題,因為原版的MySQL並沒有提供這樣的資訊。在MySQL 5.7版本中,其設計方式是將組提交的資訊存放在GTID中。那麼如果使用者沒有開啟GTID功能,即將引數gtid_mode設定為OFF呢?故MySQL 5.7又引入了稱之為Anonymous_Gtid(ANONYMOUS_GTID_LOG_EVENT)的二進位制日誌event型別