作者介紹
高強, DBAplus社群聯(lián)合發(fā)起人,開源技術(shù)專家。擅長MySQL、PostgreSQL等產(chǎn)品的實施、運維和故障處理。曾參與多個省級政府單位項目的實施和運維工作,具有豐富的運維經(jīng)驗。
關(guān)于MySQL主從復制
復制技術(shù)顧名思義,就是通過數(shù)據(jù)庫的復制技術(shù)以一份數(shù)據(jù)為主,復制成另一份存放,數(shù)據(jù)來源的那一份做為主庫,存放復制數(shù)據(jù)的的稱為從庫。MySQL的復制方案有很多,比如主從復制、半同步復制、多主還有主主復制等?;径际鞘峭ㄟ^把主庫的操作寫入二進制日志,將二進制日志傳送到從庫并且重演日志中記錄的操作跟進主庫狀態(tài)以便達到在從庫數(shù)據(jù)同步的效果。
其中, 主從復制可以變換、擴展出很多的組合方法,比如多源復制(多臺master將數(shù)據(jù)發(fā)送到1臺數(shù)據(jù)庫)、1主多從或者還有從服務器再延伸出從服務器。
下面列舉一些數(shù)據(jù)庫主從復制架構(gòu):
注:主庫為Master(1,2,..,N),從庫為Slave(1,2,...,N)。

主從復制有如下一些優(yōu)勢:
分擔負載: 對業(yè)務進行讀寫分離,減輕主庫I/O負載,將部分壓力分擔到從庫上,縮短客戶查詢響應時間。
增加健壯性: 在主庫出現(xiàn)問題時,可通過多種方案將從庫設置為主庫,替換主庫支撐業(yè)務,縮短停機窗口。
有利備份: 在從庫上備份,即不影響主庫的事務,也不影響主庫性能和磁盤空間。
查詢分析: 從庫可以作為統(tǒng)計、報表等數(shù)據(jù)分析工作所使用的的OLAP庫。
異地備份: 將從庫放置在異地可作為異地數(shù)據(jù)同步備份所用。
從MySQL的5.7版本開始支持多源主從復制技術(shù)(Multi-Source Replication),就是將多個數(shù)據(jù)庫(Master)的數(shù)據(jù)集中發(fā)送到1臺從庫(Slave)上,該技術(shù)也具有剛才上文提到的主從復制的優(yōu)勢,除了這些,它的獨特性還在于:
匯聚數(shù)據(jù): 尤其是在分庫分表的一些場景中,數(shù)據(jù)集中統(tǒng)計分析操作可以在1臺從庫服務器上實現(xiàn)。
節(jié)省成本: 數(shù)據(jù)集中存放可避免服務器等軟硬件資源浪費,5.7之前1主1從或者1主多從的方案需要為每個主機都安置一臺備機;5.7推出多源復制之后,可以將多個從庫進行合并,至于是合并存放在高端還是低端服務器上,取決于分析、統(tǒng)計等業(yè)務在整體業(yè)務中的優(yōu)先級、繁忙程度等因素。
集中備份: 方便在一臺服務器備份所有已收到的數(shù)據(jù)庫數(shù)據(jù)。
異地災備: 將從庫放在距離遠的地方,可用于異地備份項目。
基本的1主1從復制實現(xiàn)過程
下面咱們先循序漸進簡單了解一下基本的1主1從(1 master,1 slave)復制的實現(xiàn)過程:
圖中Master為主庫的主機名,Slave為從庫主機名。同步的數(shù)據(jù)庫名為Music。從庫接收主庫(binlog dump線程)發(fā)過來的Binary Log,通過從庫的I/O線程(I/O thread)將日志寫入從庫的Relay Log中,然后通過SQL線程(SQL thread)將日志的內(nèi)容應用到從庫中。
在從庫上通過命令可以看到2個必備進程(I/O thread和SQL thread)在待命狀態(tài),線程狀態(tài)如下:

線程的功能主要通過state字段確認:
I/O線程:
Waiting for master to send event
SQL(Coordinator)線程:
Slave has read all relay log; waiting for more updates
開啟并發(fā)后還會有以下線程:
Worker線程:
Waiting for an event from Coordinator
多源復制的實現(xiàn)與1主1從的類似,都是發(fā)送二進制日志再重演,但是在SQL線程(SQL thread)上有略微區(qū)別,會為每個主庫實例提供一套SQL和IO線程:

配置多源復制的操作方法
多源復制的配置比較簡單:
stop slave;
SET GLOBAL master_info_repository = 'TABLE';
SET GLOBAL relay_log_info_repository = 'TABLE';
change master to master_host='192.168.5.160',master_user='slave1',master_password='gaoqiang' for channel 'master1';
change master to master_host='192.168.5.163',master_user='slave1',master_password='gaoqiang' for channel 'master2';