MySQL 主從複製有三種方式:基於SQL語句的複製(statement-based replication,SBR),基於行的複製(row-based replication,RBR),混合模式複製(mixed-based replication,MBR)。對應的binlog檔案的格式也有三種:STATEMENT,ROW,MIXED。
l Statement-base Replication (SBR)就是記錄sql語句在bin log中,Mysql 5.1.4 及之前的版本都是使用的這種複製格式。優點是隻需要記錄會修改資料的sql語句到binlog中,減少了binlog日質量,節約I/O,提高效能。缺點是在某些情況下,會導致主從節點中資料不一致(比如sleep(),now()等)。
l Row-based Relication(RBR)是mysql master將SQL語句分解為基於Row更改的語句並記錄在bin log中,也就是隻記錄哪條資料被修改了,修改成什麼樣。優點是不會出現某些特定情況下的儲存過程、或者函式、或者trigger的呼叫或者觸發無法被正確複製的問題。缺點是會產生大量的日誌,尤其是修改table的時候會讓日誌暴增,同時增加bin log同步時間。也不能透過bin log解析獲取執行過的sql語句,只能看到發生的data變更。
l Mixed-format Replication(MBR),MySQL NDB cluster 7.3 和7.4 使用的MBR。是以上兩種模式的混合,對於一般的複製使用STATEMENT模式儲存到binlog,對於STATEMENT模式無法複製的操作則使用ROW模式來儲存,MySQL會根據執行的SQL語句選擇日誌儲存方式。
MySQL 主從複製概念
MySQL 主從複製是指資料可以從一個MySQL資料庫伺服器主節點複製到一個或多個從節點。MySQL 預設採用非同步複製方式,這樣從節點不用一直訪問主伺服器來更新自己的資料,資料的更新可以在遠端連線上進行,從節點可以複製主資料庫中的所有資料庫或者特定的資料庫,或者特定的表。
MySQL 主從複製主要用途l 讀寫分離
在開發工作中,有時候會遇見某個sql 語句需要鎖表,導致暫時不能使用讀的服務,這樣就會影響現有業務,使用主從複製,讓主庫負責寫,從庫負責讀,這樣,即使主庫出現了鎖表的情景,透過讀從庫也可以保證業務的正常運作。
l 資料實時備份,當系統中某個節點發生故障時,可以方便的故障切換
l 高可用HA
l 架構擴充套件
隨著系統中業務訪問量的增大,如果是單機部署資料庫,就會導致I/O訪問頻率過高。有了主從複製,增加多個數據儲存節點,將負載分佈在多個從節點上,降低單機磁碟I/O訪問的頻率,提高單個機器的I/O效能。
MySQL 主從形式一主一從
一主多從,提高系統的讀效能
一主一從和一主多從是最常見的主從架構,實施起來簡單並且有效,不僅可以實現HA,而且還能讀寫分離,進而提升叢集的併發能力。
多主一從 (從5.7開始支援)
多主一從可以將多個mysql資料庫備份到一臺儲存效能比較好的伺服器上。
雙主複製
雙主複製,也就是互做主從複製,每個master既是master,又是另外一臺伺服器的slave。這樣任何一方所做的變更,都會透過複製應用到另外一方的資料庫中。
級聯複製
級聯複製模式下,部分slave的資料同步不連線主節點,而是連線從節點。因為如果主節點有太多的從節點,就會損耗一部分效能用於replication,那麼我們可以讓3~5個從節點連線主節點,其它從節點作為二級或者三級與從節點連線,這樣不僅可以緩解主節點的壓力,並且對資料一致性沒有負面影響。
MySQL 主從複製原理MySQL主從複製涉及到三個執行緒,一個執行在主節點(log dump thread),其餘兩個(I/O thread, SQL thread)執行在從節點,如下圖所示:
l 主節點 binary log dump 執行緒
當從節點連線主節點時,主節點會建立一個log dump 執行緒,用於傳送bin-log的內容。在讀取bin-log中的操作時,此執行緒會對主節點上的bin-log加鎖,當讀取完成,甚至在發動給從節點之前,鎖會被釋放。
l 從節點I/O執行緒
當從節點上執行`start slave`命令之後,從節點會建立一個I/O執行緒用來連線主節點,請求主庫中更新的bin-log。I/O執行緒接收到主節點binlog dump 程序發來的更新之後,儲存在本地relay-log中。
l 從節點SQL執行緒
SQL執行緒負責讀取relay log中的內容,解析成具體的操作並執行,最終保證主從資料的一致性。
對於每一個主從連線,都需要三個程序來完成。當主節點有多個從節點時,主節點會為每一個當前連線的從節點建一個binary log dump 程序,而每個從節點都有自己的I/O程序,SQL程序。從節點用兩個執行緒將從主庫拉取更新和執行分成獨立的任務,這樣在執行同步資料任務的時候,不會降低讀操作的效能。比如,如果從節點沒有執行,此時I/O程序可以很快從主節點獲取更新,儘管SQL程序還沒有執行。如果在SQL程序執行之前從節點服務停止,至少I/O程序已經從主節點拉取到了最新的變更並且儲存在本地relay日誌中,當服務再次起來之後,就可以完成資料的同步。
要實施複製,首先必須開啟Master 端的binary log(bin-log)功能,否則無法實現。
因為整個複製過程實際上就是Slave 從Master 端獲取該日誌然後再在自己身上完全順序的執行日誌中所記錄的各種操作。如下圖所示:
複製的基本過程如下:
從節點上的I/O 程序連線主節點,並請求從指定日誌檔案的指定位置(或者從最開始的日誌)之後的日誌內容;
主節點接收到來自從節點的I/O請求後,透過負責複製的I/O程序根據請求資訊讀取指定日誌指定位置之後的日誌資訊,返回給從節點。返回資訊中除了日誌所包含的資訊之外,還包括本次返回的資訊的bin-log file 的以及bin-log position;從節點的I/O程序接收到內容後,將接收到的日誌內容更新到本機的relay log中,並將讀取到的binary log檔名和位置儲存到master-info 檔案中,以便在下一次讀取的時候能夠清楚的告訴Master“我需要從某個bin-log 的哪個位置開始往後的日誌內容,請發給我”;
Slave 的 SQL執行緒檢測到relay-log 中新增加了內容後,會將relay-log的內容解析成在祝節點上實際執行過的操作,並在本資料庫中執行。
MySQL 主從複製模式MySQL 主從複製預設是非同步的模式。MySQL增刪改操作會全部記錄在binary log中,當slave節點連線master時,會主動從master處獲取最新的bin log檔案。並把bin log中的sql relay。
l 非同步模式(mysql async-mode)
非同步模式如下圖所示,這種模式下,主節點不會主動push bin log到從節點,這樣有可能導致failover的情況下,也許從節點沒有即時地將最新的bin log同步到本地。
l 半同步模式(mysql semi-sync)
這種模式下主節點只需要接收到其中一臺從節點的返回資訊,就會commit;否則需要等待直到超時時間然後切換成非同步模式再提交;這樣做的目的可以使主從資料庫的資料延遲縮小,可以提高資料安全性,確保了事務提交後,binlog至少傳輸到了一個從節點上,不能保證從節點將此事務更新到db中。效能上會有一定的降低,響應時間會變長。如下圖所示:
半同步模式不是mysql內建的,從mysql 5.5開始整合,需要master 和slave 安裝外掛開啟半同步模式。
l 全同步模式
全同步模式是指主節點和從節點全部執行了commit並確認才會向客戶端返回成功。
binlog記錄格式MySQL 主從複製有三種方式:基於SQL語句的複製(statement-based replication,SBR),基於行的複製(row-based replication,RBR),混合模式複製(mixed-based replication,MBR)。對應的binlog檔案的格式也有三種:STATEMENT,ROW,MIXED。
l Statement-base Replication (SBR)就是記錄sql語句在bin log中,Mysql 5.1.4 及之前的版本都是使用的這種複製格式。優點是隻需要記錄會修改資料的sql語句到binlog中,減少了binlog日質量,節約I/O,提高效能。缺點是在某些情況下,會導致主從節點中資料不一致(比如sleep(),now()等)。
l Row-based Relication(RBR)是mysql master將SQL語句分解為基於Row更改的語句並記錄在bin log中,也就是隻記錄哪條資料被修改了,修改成什麼樣。優點是不會出現某些特定情況下的儲存過程、或者函式、或者trigger的呼叫或者觸發無法被正確複製的問題。缺點是會產生大量的日誌,尤其是修改table的時候會讓日誌暴增,同時增加bin log同步時間。也不能透過bin log解析獲取執行過的sql語句,只能看到發生的data變更。
l Mixed-format Replication(MBR),MySQL NDB cluster 7.3 和7.4 使用的MBR。是以上兩種模式的混合,對於一般的複製使用STATEMENT模式儲存到binlog,對於STATEMENT模式無法複製的操作則使用ROW模式來儲存,MySQL會根據執行的SQL語句選擇日誌儲存方式。
GTID複製模式@ 在傳統的複製裡面,當發生故障,需要主從切換,需要找到binlog和pos點,然後將主節點指向新的主節點,相對來說比較麻煩,也容易出錯。在MySQL 5.6裡面,不用再找binlog和pos點,我們只需要知道主節點的ip,埠,以及賬號密碼就行,因為複製是自動的,MySQL會透過內部機制GTID自動找點同步。
@ 多執行緒複製(基於庫),在MySQL 5.6以前的版本,slave的複製是單執行緒的。一個事件一個事件的讀取應用。而master是併發寫入的,所以延時是避免不了的。唯一有效的方法是把多個庫放在多臺slave,這樣又有點浪費伺服器。在MySQL 5.6裡面,我們可以把多個表放在多個庫,這樣就可以使用多執行緒複製。
基於GTID複製實現的工作原理主節點更新資料時,會在事務前產生GTID,一起記錄到binlog日誌中。
從節點的I/O執行緒將變更的bin log,寫入到本地的relay log中。
SQL執行緒從relay log中獲取GTID,然後對比本地binlog是否有記錄(所以MySQL從節點必須要開啟binary log)。
如果有記錄,說明該GTID的事務已經執行,從節點會忽略。
如果沒有記錄,從節點就會從relay log中執行該GTID的事務,並記錄到bin log。
在解析過程中會判斷是否有主鍵,如果沒有就用二級索引,如果有就用全部掃描。
總結Mysql 主從複製是mysql 高可用,高效能的基礎,有了這個基礎,mysql 的部署會變得簡單、靈活並且具有多樣性,從而可以根據不同的業務場景做出靈活的調整。