1 Mysql主從復制工作原理
1.Master 數(shù)據(jù)庫只要發(fā)生變化,立馬記錄到Binary log 日志文件中
2.Slave數(shù)據(jù)庫啟動一個I/O thread連接Master數(shù)據(jù)庫,請求Master變化的二進制日志
3.Slave I/O獲取到的二進制日志,保存到自己的Relay log 日志文件中。
4.Slave 有一個 SQL thread定時檢查Realy log是否變化,變化那么就更新數(shù)據(jù)

2 Mysql主從復制方式
(1)主庫刷盤策略
為了保證Binlog的安全,MySQL引入sync_binlog參數(shù)來控制BINLOG刷新到磁盤的頻率。

sync_binlog=1,表示事務提交之前,MySQL都需要先把BINLOG刷新到磁盤,這樣的話,即使出現(xiàn)數(shù)據(jù)庫主機操作系統(tǒng)崩潰或者主機突然掉電的情況,系統(tǒng)最多損失prepared狀態(tài)的事務
sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系統(tǒng)自己控制文件緩存的刷新
sync_binlog=N,如果N不等于0或者1,刷新方式同sync_binlog=1類似,只不過此時會延長刷新頻率至N次binlog提交組之后
(2)異步復制
MySQL主從異步復制是最常見的復制場景。數(shù)據(jù)的完整性依賴于主庫BINLOG的不丟失,只要主庫的BINLOG不丟失,那么就算主庫宕機了,我們還可以通過BINLOG把丟失的部分數(shù)據(jù)通過手工同步到從庫上去。
異步復制模式下,主庫和從庫的數(shù)據(jù)之間會存在一定的延遲。這樣存在一個隱患:

如上圖,當在主庫上寫入一個事務并提交成功,而從庫尚未得到主庫的BINLOG日志時,主庫由于磁盤損壞、內(nèi)存故障、斷電等原因意外宕機,導致主從不一致。
(3)半同步復制
為了保證主庫上的每一個BINLOG都能夠被可靠地復制到從庫上,MySQL引入了半同步復制。
傳統(tǒng)半同步
傳統(tǒng)半同步的處理流程是,主庫在每次事務成功提交時,并不及時反饋給前端應用用戶,而是等待至少一個從庫接收到BINLOG事務并成功寫入中繼日志后,主庫才返回Commit操作成功給客戶端。
傳統(tǒng)半同步復制保證了事務成功提交后,至少有兩份日志記錄,一份在主庫的BINLOG日志上,另一份在至少一個從庫的中繼日志Relay Log上,從而更進一步保證了數(shù)據(jù)的完整性。
然而在傳統(tǒng)的半同步復制中,主庫寫數(shù)據(jù)到BINLOG,且執(zhí)行Commit操作后,會一直等待從庫的ACK,即從庫寫入Relay Log后,并將數(shù)據(jù)落盤,返回給主庫消息,通知主庫可以返回前端應用操作成功,這樣會出現(xiàn)一個問題,就是實際上主庫已經(jīng)將該事務Commit到了事務引擎層,應用已經(jīng)可以可以看到數(shù)據(jù)發(fā)生了變化,只是在等待返回而已,如果此時主庫宕機,有可能從庫還沒能寫入Relay Log,就會發(fā)生主從庫不一致。
增強半同步
增強半同步復制就是為了解決上面的問題,做了微調(diào),即主庫寫數(shù)據(jù)到BINLOG后,就開始等待從庫的應答ACK,直到至少一個從庫寫入Relay Log后,并將數(shù)據(jù)落盤,然后返回給主庫消息,通知主庫可以執(zhí)行Commit操作,然后主庫開始提交到事務引擎層,應用此時可以看到數(shù)據(jù)發(fā)生了變化。增強半同步復制的大致流程如下圖所示。

從上圖可以看出,增強半同步也并不完美。加入Master在接受到ACK之前發(fā)生宕機,此時BINLOG可能已經(jīng)到達Slave,也可能沒有到達Slave,想做到主從完全一致,仍然很困難。不過由于Master在接受到ACK之前,并不會給客戶端應答,所以還是有機會做到強一致的,此處不展開討論。
2.3 組復制(MGR)
2.3.1 定義
MGR 是一個新的高可用與高擴展的方案,集群中的任何節(jié)點數(shù)據(jù)都是一樣的,可以實現(xiàn)任何節(jié)點都可以寫入,實現(xiàn)了真正意義上的多主。
2.3.2 架構(gòu)

API層:負責完成和MySQL Server的交互,得到Server狀態(tài),完成事務的管理。
組件層:主要包括3個特定組件
Capture負責收集事務執(zhí)行的相關(guān)信息
Applier負責應用集群事務到本地
Recovery負責節(jié)點的數(shù)據(jù)恢復。
復制層:負責沖突驗證,接收和應用集群事務。
集群通信層:基于Paxos協(xié)議的集群通信引擎,以及和上層組件的交互接口。
2.3.3 復制過程

事務在引擎層完成Prepare,寫B(tài)inlog之前會被MySQL預設(shè)的鉤子(Hook)before_commit攔截
在MGR層,事務執(zhí)行相關(guān)的信息打包,通過Paxos一致性協(xié)議(Consensus)進行全局排序后發(fā)送給MGR各個節(jié)點
當超過半數(shù)(N/2+1)的節(jié)點(包括它自己)回應后,發(fā)送消息告訴所有節(jié)點,這個數(shù)據(jù)包同步成功
各節(jié)點獨自進行認證(Certify)
若認證通過,本地節(jié)點寫B(tài)inlog完成提交
異地節(jié)點寫Relay Log(常規(guī)主從同步使用的relaylog不是同一組),由建立的復制通道(Replication Channel)group_replication_applier完成事務并行回放
若認證不通過,就會進行回滾(Rollback)
2.3.4 模式
單主模式
在此模式下,組有一個設(shè)置為讀寫模式的單主server。 組中的所有其他成員被自動設(shè)置為只讀模式(超級只讀模式)。主服務器通常是用于引導組的第一個server,所有其他加入的server自動從主服務器同步并設(shè)置為只讀。
多主模式
在多主模式下,沒有單主模式的概念。沒有必要使用選主程序,因為不同server成員之間沒有 什么特殊的差異。
3.總結(jié)
即使目前MySQL的高可用和數(shù)據(jù)一致性有很多方案,但是我們還不能完全兼顧可用性和一致性,所以我們選擇方案時要根據(jù)我們業(yè)務需求,合理選擇