深度探索MySQL主從複製原理

深度探索MySQL主從複製原理

一 、概要

MySQL Replication (MySQL 主從複製) 是什麼?mysql

爲何要主從複製以及它的實現原理是什麼?sql

1.1 MySQL 主從複製概念

MySQL 主從複製是指數據能夠從一個MySQL數據庫服務器主節點複製到一個或多個從節點。MySQL 默認採用異步複製方式,這樣從節點不用一直訪問主服務器來更新本身的數據,數據的更新能夠在遠程鏈接上進行,從節點能夠複製主數據庫中的全部數據庫或者特定的數據庫,或者特定的表。數據庫

1.2 MySQL 主從複製主要用途

  1. 讀寫分離

在開發工做中,有時候會碰見某個sql 語句須要鎖表,致使暫時不能使用讀的服務,這樣就會影響現有業務,使用主從複製,讓主庫負責寫,從庫負責讀,這樣,即便主庫出現了鎖表的情景,經過讀從庫也能夠保證業務的正常運做。安全

  1. 數據實時備份,當系統中某個節點發生故障時,能夠方便的故障切換
  2. 高可用HA
  3. 架構擴展

隨着系統中業務訪問量的增大,若是是單機部署數據庫,就會致使I/O訪問頻率太高。有了主從複製,增長多個數據存儲節點,將負載分佈在多個從節點上,下降單機磁盤I/O訪問的頻率,提升單個機器的I/O性能。服務器

二 、MySQL 主從形式一主一從

2.1 一主多從,提升系統的讀性能

undefined

一主一從和一主多從是最多見的主從架構,實施起來簡單而且有效,不只能夠實現HA,並且還能讀寫分離,進而提高集羣的併發能力。多線程

2.2 多主一從(從5.7開始支持)

undefined

多主一從能夠將多個MySQL數據庫備份到一臺存儲性能比較好的服務器上。架構

2.3 雙主複製

雙主複製,也就是互作主從複製,每一個master既是master,又是另一臺服務器的slave。這樣任何一方所作的變動,都會經過複製應用到另一方的數據庫中。併發

2.4 級聯複製

undefined

級聯複製模式下,部分slave的數據同步不鏈接主節點,而是鏈接從節點。由於若是主節點有太多的從節點,就會損耗一部分性能用於replication,那麼咱們可讓3~5個從節點鏈接主節點,其它從節點做爲二級或者三級與從節點鏈接,這樣不只能夠緩解主節點的壓力,而且對數據一致性沒有負面影響。異步

三 、MySQL 主從複製原理

MySQL主從複製涉及到三個線程,一個運行在主節點(log dump thread),其他兩個(I/O thread, SQL thread)運行在從節點,以下圖所示:async

undefined

3.1 主節點 binary log dump 線程

當從節點鏈接主節點時,主節點會建立一個log dump 線程,用於發送bin-log的內容。在讀取bin-log中的操做時,此線程會對主節點上的bin-log加鎖,當讀取完成,甚至在發動給從節點以前,鎖會被釋放。

3.1.1 從節點I/O線程

當從節點上執行start slave命令以後,從節點會建立一個I/O線程用來鏈接主節點,請求主庫中更新的bin-log。I/O線程接收到主節點binlog dump 進程發來的更新以後,保存在本地relay-log中。

3.1.2 從節點SQL線程

SQL線程負責讀取relay log中的內容,解析成具體的操做並執行,最終保證主從數據的一致性。

對於每個主從鏈接,都須要三個進程來完成。當主節點有多個從節點時,主節點會爲每個當前鏈接的從節點建一個binary log dump 進程,而每一個從節點都有本身的I/O進程,SQL進程。從節點用兩個線程將從主庫拉取更新和執行分紅獨立的任務,這樣在執行同步數據任務的時候,不會下降讀操做的性能。好比,若是從節點沒有運行,此時I/O進程能夠很快從主節點獲取更新,儘管SQL進程尚未執行。若是在SQL進程執行以前從節點服務中止,至少I/O進程已經從主節點拉取到了最新的變動而且保存在本地relay日誌中,當服務再次起來以後,就能夠完成數據的同步。

要實施複製,首先必須打開Master 端的binary log(bin-log)功能,不然沒法實現。

由於整個複製過程實際上就是Slave 從Master 端獲取該日誌而後再在本身身上徹底順序的執行日誌中所記錄的各類操做。以下圖所示:

undefined

3.3.3 複製的基本過程

  1. 從節點上的I/O 進程鏈接主節點,並請求從指定日誌文件的指定位置(或者從最開始的日誌)以後的日誌內容;
  2. 主節點接收到來自從節點的I/O請求後,經過負責複製的I/O進程根據請求信息讀取指定日誌指定位置以後的日誌信息,返回給從節點。返回信息中除了日誌所包含的信息以外,還包括本次返回的信息的bin-log file 的以及bin-log position;
  3. 從節點的I/O進程接收到內容後,將接收到的日誌內容更新到本機的relay log中,並將讀取到的binary log文件名和位置保存到master-info 文件中,以便在下一次讀取的時候可以清楚的告訴Master「我須要從某個bin-log 的哪一個位置開始日後的日誌內容,請發給我」;
  4. Slave 的 SQL線程檢測到relay-log 中新增長了內容後,會將relay-log的內容解析成在祝節點上實際執行過的操做,並在本數據庫中執行。

3.2 MySQL 主從複製模式

MySQL 主從複製默認是異步的模式。MySQL增刪改操做會所有記錄在binary log中,當slave節點鏈接master時,會主動從master處獲取最新的bin log文件。並把bin log中的sql relay。

3.2.1 異步模式(mysql async-mode)

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

undefined

3.2.2 半同步模式(mysql semi-sync)

這種模式下主節點只須要接收到其中一臺從節點的返回信息,就會commit;不然須要等待直到超時時間而後切換成異步模式再提交;這樣作的目的可使主從數據庫的數據延遲縮小,能夠提升數據安全性,確保了事務提交後,binlog至少傳輸到了一個從節點上,不能保證從節點將此事務更新到db中。性能上會有必定的下降,響應時間會變長。以下圖所示:

undefined

半同步模式不是MySQL內置的,從MySQL5.5開始集成,須要master 和slave 安裝插件開啓半同步模式。

3.3.3 全同步模式

全同步模式是指主節點和從節點所有執行了commit並確認纔會向客戶端返回成功。

3.3.4 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中,MySQL5.1.4 及以前的版本都是使用的這種複製格式。優勢是隻須要記錄會修改數據的sql語句到binlog中,減小了binlog日質量,節約I/O,提升性能。缺點是在某些狀況下,會致使主從節點中數據不一致(好比sleep(),now()等)。
  2. Row-based Relication(RBR)是mysql master將SQL語句分解爲基於Row更改的語句並記錄在bin log中,也就是隻記錄哪條數據被修改了,修改爲什麼樣。優勢是不會出現某些特定狀況下的存儲過程、或者函數、或者trigger的調用或者觸發沒法被正確複製的問題。缺點是會產生大量的日誌,尤爲是修改table的時候會讓日誌暴增,同時增長bin log同步時間。也不能經過bin log解析獲取執行過的sql語句,只能看到發生的data變動。
  3. Mixed-format Replication(MBR),MySQL NDB cluster 7.3 和7.4 使用的MBR。是以上兩種模式的混合,對於通常的複製使用STATEMENT模式保存到binlog,對於STATEMENT模式沒法複製的操做則使用ROW模式來保存,MySQL會根據執行的SQL語句選擇日誌保存方式。

3.3.5 GTID複製模式

  1. 在傳統的複製裏面,當發生故障,須要主從切換,須要找到binlog和pos點,而後將主節點指向新的主節點,相對來講比較麻煩,也容易出錯。在MySQL 5.6裏面,不用再找binlog和pos點,咱們只須要知道主節點的ip,端口,以及帳號密碼就行,由於複製是自動的,MySQL會經過內部機制GTID自動找點同步。
  2. 多線程複製(基於庫),在MySQL 5.6之前的版本,slave的複製是單線程的。一個事件一個事件的讀取應用。而master是併發寫入的,因此延時是避免不了的。惟一有效的方法是把多個庫放在多臺slave,這樣又有點浪費服務器。在MySQL 5.6裏面,咱們能夠把多個表放在多個庫,這樣就可使用多線程複製。

3.3.6 基於GTID複製實現的工做原理

  1. 主節點更新數據時,會在事務前產生GTID,一塊兒記錄到binlog日誌中。
  2. 從節點的I/O線程將變動的bin log,寫入到本地的relay log中。
  3. SQL線程從relay log中獲取GTID,而後對比本地binlog是否有記錄(因此MySQL從節點必需要開啓binary log)。
  4. 若是有記錄,說明該GTID的事務已經執行,從節點會忽略。若是沒有記錄,從節點就會從relay log中執行該GTID的事務,並記錄到bin log。
  5. 在解析過程當中會判斷是否有主鍵,若是沒有就用二級索引,若是有就用所有掃描。

四 、總結

MySQL主從複製是MySQL高可用,高性能的基礎,有了這個基礎,MySQL的部署會變得簡單、靈活而且具備多樣性,從而能夠根據不一樣的業務場景作出靈活的調整。

相關文章
相關標籤/搜索