主從復制原理

原地址:https://baijiahao.baidu.com/s?id=1617888740370098866&wfr=spider&for=pc

概念

MySQL 主從復制是指數(shù)據(jù)可以從一個MySQL數(shù)據(jù)庫服務器主節(jié)點復制到一個或多個從節(jié)點。MySQL 默認采用異步復制方式,這樣從節(jié)點不用一直訪問主服務器來更新自己的數(shù)據(jù),數(shù)據(jù)的更新可以在遠程連接上進行,從節(jié)點可以復制主數(shù)據(jù)庫中的所有數(shù)據(jù)庫或者特定的數(shù)據(jù)庫,或者特定的表。

主要用途

1. 讀寫分離

在開發(fā)工作中,有時候會遇見某個sql 語句需要鎖表,導致暫時不能使用讀的服務,這樣就會影響現(xiàn)有業(yè)務,使用主從復制,讓主庫負責寫,從庫負責讀,這樣,即使主庫出現(xiàn)了鎖表的情景,通過讀從庫也可以保證業(yè)務的正常運作。

2. 數(shù)據(jù)實時備份

當系統(tǒng)中某個節(jié)點發(fā)生故障時,可以方便的故障切換

3. 高可用HA和架構擴展

隨著系統(tǒng)中業(yè)務訪問量的增大,如果是單機部署數(shù)據(jù)庫,就會導致I/O訪問頻率過高。有了主從復制,增加多個數(shù)據(jù)存儲節(jié)點,將負載分布在多個從節(jié)點上,降低單機磁盤I/O訪問的頻率,提高單個機器的I/O性能。

主從形式

1. 一主一從

image

一主多從,提高系統(tǒng)的讀性能。一主一從和一主多從是最常見的主從架構,實施起來簡單并且有效,不僅可以實現(xiàn)HA,而且還能讀寫分離,進而提升集群的并發(fā)能力。

2. 多主一從 (從5.7開始支持)

image

多主一從可以將多個mysql數(shù)據(jù)庫備份到一臺存儲性能比較好的服務器上。

3. 雙主復制

雙主復制,也就是互做主從復制,每個master既是master,又是另外一臺服務器的slave。這樣任何一方所做的變更,都會通過復制應用到另外一方的數(shù)據(jù)庫中。

4. 級聯(lián)復制

image

級聯(lián)復制模式下,部分slave的數(shù)據(jù)同步不連接主節(jié)點,而是連接從節(jié)點。因為如果主節(jié)點有太多的從節(jié)點,就會損耗一部分性能用于replication,那么我們可以讓3~5個從節(jié)點連接主節(jié)點,其它從節(jié)點作為二級或者三級與從節(jié)點連接,這樣不僅可以緩解主節(jié)點的壓力,并且對數(shù)據(jù)一致性沒有負面影響。

主從復制原理

MySQL主從復制涉及到三個線程,一個運行在主節(jié)點(log dump thread),其余兩個(I/O thread, SQL thread)運行在從節(jié)點,如下圖所示:

image

1. 主節(jié)點 binary log dump 線程

當從節(jié)點連接主節(jié)點時,主節(jié)點會創(chuàng)建一個log dump 線程,用于發(fā)送bin-log的內(nèi)容。在讀取bin-log中的操作時,此線程會對主節(jié)點上的bin-log加鎖,當讀取完成,甚至在發(fā)動給從節(jié)點之前,鎖會被釋放。

2.從節(jié)點I/O線程

當從節(jié)點上執(zhí)行start slave命令之后,從節(jié)點會創(chuàng)建一個I/O線程用來連接主節(jié)點,請求主庫中更新的bin-log。I/O線程接收到主節(jié)點binlog dump 進程發(fā)來的更新之后,保存在本地relay-log中。

3.從節(jié)點SQL線程

SQL線程負責讀取relay log中的內(nèi)容,解析成具體的操作并執(zhí)行,最終保證主從數(shù)據(jù)的一致性。

對于每一個主從連接,都需要三個進程來完成。當主節(jié)點有多個從節(jié)點時,主節(jié)點會為每一個當前連接的從節(jié)點建一個binary log dump 進程,而每個從節(jié)點都有自己的I/O進程,SQL進程。從節(jié)點用兩個線程將從主庫拉取更新和執(zhí)行分成獨立的任務,這樣在執(zhí)行同步數(shù)據(jù)任務的時候,不會降低讀操作的性能。比如,如果從節(jié)點沒有運行,此時I/O進程可以很快從主節(jié)點獲取更新,盡管SQL進程還沒有執(zhí)行。如果在SQL進程執(zhí)行之前從節(jié)點服務停止,至少I/O進程已經(jīng)從主節(jié)點拉取到了最新的變更并且保存在本地relay日志中,當服務再次起來之后,就可以完成數(shù)據(jù)的同步。

要實施復制,首先必須打開Master 端的binary log(bin-log)功能,否則無法實現(xiàn)。

因為整個復制過程實際上就是Slave 從Master 端獲取該日志然后再在自己身上完全順序的執(zhí)行日志中所記錄的各種操作。如下圖所示:

image
復制的基本過程如下:
  1. 從節(jié)點上的I/O 進程連接主節(jié)點,并請求從指定日志文件的指定位置(或者從最開始的日志)之后的日志內(nèi)容;
  2. 主節(jié)點接收到來自從節(jié)點的I/O請求后,通過負責復制的I/O進程根據(jù)請求信息讀取指定日志指定位置之后的日志信息,返回給從節(jié)點。返回信息中除了日志所包含的信息之外,還包括本次返回的信息的bin-log file 的以及bin-log position;從節(jié)點的I/O進程接收到內(nèi)容后,將接收到的日志內(nèi)容更新到本機的relay log中,并將讀取到的binary log文件名和位置保存到master-info 文件中,以便在下一次讀取的時候能夠清楚的告訴Master“我需要從某個bin-log 的哪個位置開始往后的日志內(nèi)容,請發(fā)給我”;
  3. Slave 的 SQL線程檢測到relay-log 中新增加了內(nèi)容后,會將relay-log的內(nèi)容解析成在祝節(jié)點上實際執(zhí)行過的操作,并在本數(shù)據(jù)庫中執(zhí)行。

主從復制模式

MySQL 主從復制默認是異步的模式。MySQL增刪改操作會全部記錄在binary log中,當slave節(jié)點連接master時,會主動從master處獲取最新的bin log文件。并把bin log中的sql relay。

1. 異步模式(mysql async-mode)

異步模式如下圖所示,這種模式下,主節(jié)點不會主動push bin log到從節(jié)點,這樣有可能導致failover的情況下,也許從節(jié)點沒有即時地將最新的bin log同步到本地。

image
2. 半同步模式(mysql semi-sync)

這種模式下主節(jié)點只需要接收到其中一臺從節(jié)點的返回信息,就會commit;否則需要等待直到超時時間然后切換成異步模式再提交;這樣做的目的可以使主從數(shù)據(jù)庫的數(shù)據(jù)延遲縮小,可以提高數(shù)據(jù)安全性,確保了事務提交后,binlog至少傳輸?shù)搅艘粋€從節(jié)點上,不能保證從節(jié)點將此事務更新到db中。性能上會有一定的降低,響應時間會變長。如下圖所示:

image

半同步模式不是mysql內(nèi)置的,從mysql 5.5開始集成,需要master 和slave 安裝插件開啟半同步模式。

3. 全同步模式

全同步模式是指主節(jié)點和從節(jié)點全部執(zhí)行了commit并確認才會向客戶端返回成功。

binlog記錄格式

MySQL 主從復制有三種方式:基于SQL語句的復制(statement-based replication,SBR),基于行的復制(row-based replication,RBR),混合模式復制(mixed-based replication,MBR)。對應的binlog文件的格式也有三種:STATEMENT,ROW,MIXED。

  1. Statement-base Replication (SBR)就是記錄sql語句在bin log中,Mysql 5.1.4 及之前的版本都是使用的這種復制格式。優(yōu)點是只需要記錄會修改數(shù)據(jù)的sql語句到binlog中,減少了binlog日質(zhì)量,節(jié)約I/O,提高性能。缺點是在某些情況下,會導致主從節(jié)點中數(shù)據(jù)不一致(比如sleep(),now()等)。

  2. Row-based Relication(RBR)是mysql master將SQL語句分解為基于Row更改的語句并記錄在bin log中,也就是只記錄哪條數(shù)據(jù)被修改了,修改成什么樣。優(yōu)點是不會出現(xiàn)某些特定情況下的存儲過程、或者函數(shù)、或者trigger的調(diào)用或者觸發(fā)無法被正確復制的問題。缺點是會產(chǎn)生大量的日志,尤其是修改table的時候會讓日志暴增,同時增加bin log同步時間。也不能通過bin log解析獲取執(zhí)行過的sql語句,只能看到發(fā)生的data變更。

  3. Mixed-format Replication(MBR),MySQL NDB cluster 7.3 和7.4 使用的MBR。是以上兩種模式的混合,對于一般的復制使用STATEMENT模式保存到binlog,對于STATEMENT模式無法復制的操作則使用ROW模式來保存,MySQL會根據(jù)執(zhí)行的SQL語句選擇日志保存方式。

GTID復制模式
在傳統(tǒng)的復制里面,當發(fā)生故障,需要主從切換,需要找到binlog和pos點,然后將主節(jié)點指向新的主節(jié)點,相對來說比較麻煩,也容易出錯。在MySQL 5.6里面,不用再找binlog和pos點,我們只需要知道主節(jié)點的ip,端口,以及賬號密碼就行,因為復制是自動的,MySQL會通過內(nèi)部機制GTID自動找點同步。

多線程復制(基于庫),在MySQL 5.6以前的版本,slave的復制是單線程的。一個事件一個事件的讀取應用。而master是并發(fā)寫入的,所以延時是避免不了的。唯一有效的方法是把多個庫放在多臺slave,這樣又有點浪費服務器。在MySQL 5.6里面,我們可以把多個表放在多個庫,這樣就可以使用多線程復制。

基于GTID復制實現(xiàn)的工作原理
  1. 主節(jié)點更新數(shù)據(jù)時,會在事務前產(chǎn)生GTID,一起記錄到binlog日志中。
  2. 從節(jié)點的I/O線程將變更的bin log,寫入到本地的relay log中。
  3. SQL線程從relay log中獲取GTID,然后對比本地binlog是否有記錄(所以MySQL從節(jié)點必須要開啟binary log)。
  4. 如果有記錄,說明該GTID的事務已經(jīng)執(zhí)行,從節(jié)點會忽略。如果沒有記錄,從節(jié)點就會從relay log中執(zhí)行該GTID的事務,并記錄到bin log。
  5. 在解析過程中會判斷是否有主鍵,如果沒有就用二級索引,如果有就用全部掃描。

總結

Mysql 主從復制是mysql 高可用,高性能的基礎,有了這個基礎,mysql 的部署會變得簡單、靈活并且具有多樣性,從而可以根據(jù)不同的業(yè)務場景做出靈活的調(diào)整。

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

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

  • 參考:深度探索MySQL主從復制原理 MySQL 主從復制概念 MySQL 主從復制是指數(shù)據(jù)可以從一個MySQL數(shù)...
    了凡_8504閱讀 341評論 0 0
  • 1、復制概述: MySQL內(nèi)建的復制功能是構建大型,高性能應用程序的基礎。將mysql的數(shù)據(jù)分布到多個系統(tǒng)上去,這...
    魔法師_閱讀 5,753評論 0 5
  • Mysql主從復制原理 主從復制是指一臺服務器充當主數(shù)據(jù)庫服務器,另一臺或多臺服務器充當從數(shù)據(jù)庫服務器,主服務器中...
    我的小熊不見了閱讀 359評論 0 2
  • 很早就整理了,現(xiàn)在閑了寫出來。 解決場景 當一臺數(shù)據(jù)庫服務器塌機后,能使用主/從數(shù)據(jù)庫快速切換。保證項目的穩(wěn)定性。...
    AISpider閱讀 728評論 0 0
  • 有時會覺得很幸福,莫名其妙的,在想到爸爸發(fā)起脾氣然后接下里一句又是關心,很心疼他 不信仰什么東西,心中也無敬畏, ...
    Goya_f5ae閱讀 130評論 0 0

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