MySQL的主从复制
MySQL的主從復制
目錄
- 為什么需要主從復制?
- MySQL 主從復制概念
- MySQL 主從復制主要用途
- MySQL主從形式 - 一主一從
- 一主多從,提高系統的讀性能
- 多主一從 (從5.7開始支持)
- 雙主復制
- 級聯復制
 
- MySQL 主從復制原理
- MySQL主從復制的過程
- MySQL 主從復制模式 - 異步模式(mysql async-mode)
- 半同步模式(mysql semi-sync)
- 全同步模式
 
- MySQL的復制機制 - binlog記錄模式
- GTID復制模式
 
- mysql主從同步延時分析 - 多線程復制MTS
 
回到頂部
為什么需要主從復制?
回到頂部
MySQL 主從復制概念
MySQL 主從復制是指數據可以從一個MySQL數據庫服務器主節點復制到一個或多個從節點。MySQL 默認采用異步復制方式,這樣從節點不用一直訪問主服務器來更新自己的數據,數據的更新可以在遠程連接上進行,從節點可以復制主數據庫中的所有數據庫或者特定的數據庫,或者特定的表。
回到頂部
MySQL 主從復制主要用途
-  讀寫分離 在開發工作中,有時候會遇見某個sql 語句需要鎖表,導致暫時不能使用讀的服務,這樣就會影響現有業務,使用主從復制,讓主庫負責寫,從庫負責讀,這樣,即使主庫出現了鎖表的情景,通過讀從庫也可以保證業務的正常運作。 
-  數據實時備份,當系統中某個節點出現故障的時候,方便切換 
-  高可用HA 
-  架構擴展 隨著系統中業務訪問量的增大,如果是單機部署數據庫,就會導致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)運行在從節點,如下圖所示:
- 主節點 binary log dump 線程作用
當從節點連接主節點時,主節點會創建一個log dump 線程,用于發送bin-log的內容。在讀取bin-log中的操作時,此線程會對主節點上的bin-log加鎖,當讀取完成,甚至在發動給從節點之前,鎖會被釋放。
- 從節點I/O線程作用
當從節點上執行start slave命令之后,從節點會創建一個I/O線程用來連接主節點,請求主庫中更新的bin-log。I/O線程接收到主節點binlog dump 進程發來的更新之后,保存在本地relay-log中。
- 從節點SQL線程作用
SQL線程負責讀取relay log中的內容,解析成具體的操作并執行,最終保證主從數據的一致性。
對于每一個主從連接,都需要三個進程來完成。當主節點有多個從節點時,主節點會為每一個當前連接的從節點建一個binary log dump 進程,而每個從節點都有自己的I/O進程,SQL進程。從節點用兩個線程將從主庫拉取更新和執行分成獨立的任務,這樣在執行同步數據任務的時候,不會降低讀操作的性能。比如,如果從節點沒有運行,此時I/O進程可以很快從主節點獲取更新,盡管SQL進程還沒有執行。如果在SQL進程執行之前從節點服務停止,至少I/O進程已經從主節點拉取到了最新的變更并且保存在本地relay日志中,當服務再次起來之后,就可以完成數據的同步。
回到頂部
MySQL主從復制的過程
要實施復制,首先必須打開Master 端的binary log(bin-log)功能,否則無法實現。因為整個復制過程實際上就是Slave 從Master 端獲取該日志然后再在自己身上完全順序的執行日志中所記錄的各種操作
回到頂部
MySQL 主從復制模式
MySQL 主從復制默認是異步的模式。MySQL增刪改操作會全部記錄在binary log中,當slave節點連接master時,會主動從master處獲取最新的bin log文件。并把bin log中的sql relay。
異步模式(mysql async-mode)
異步模式如下圖所示,這種模式下,主節點不會主動push bin log到從節點,這樣有可能導致failover的情況下,也許從節點沒有即時地將最新的bin log同步到本地。
半同步模式(mysql semi-sync)
這種模式下主節點只需要接收到其中一臺從節點的返回信息,就會commit;否則需要等待直到超時時間然后切換成異步模式再提交;這樣做的目的可以使主從數據庫的數據延遲縮小,可以提高數據安全性,確保了事務提交后,binlog至少傳輸到了一個從節點上,不能保證從節點將此事務更新到db中。性能上會有一定的降低,響應時間會變長。如下圖所示:
全同步模式
全同步模式是指主節點和從節點全部執行了commit并確認才會向客戶端返回成功。
回到頂部
MySQL的復制機制
binlog記錄模式
MySQL 主從復制有三種方式:基于SQL語句的復制(statement-based replication,SBR),基于行的復制(row-based replication,RBR),混合模式復制(mixed-based replication,MBR)。對應的binlog文件的格式也有三種:STATEMENT,ROW,MIXED。
GTID復制模式
在MySQL 5.6里面,不用再找binlog和pos點,我們只需要知道主節點的ip,端口,以及賬號密碼就行,因為復制是自動的,MySQL會通過內部機制GTID自動找點同步。
基于GTID復制實現的工作原理
回到頂部
mysql主從同步延時分析
mysql的主從復制都是單線程的操作,主庫對所有DDL和DML產生的日志寫進binlog,由于binlog是順序寫,所以效率很高,slave的sql thread線程將主庫的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是隨機的,不是順序,所以成本要高很多,另一方面,由于sql thread也是單線程的,當主庫的并發較高時,產生的DML數量超過slave的SQL thread所能處理的速度,或者當slave中有大型query語句產生了鎖等待,那么延時就產生了。
解決方案:
mysql5.7之后使用MTS并行復制技術
多線程復制MTS
在MYSQL5.6版本中,多線程復制基于schema來實現,將多個數據庫下的事務按照數據庫拆分到多個線程上執行,保證數據庫級別的事務一致性。
在MYSQL5.7版本后,多線程復制基于主庫上并發信息來實現,主庫上并發提交的事務不存在事務沖突,在從庫上拆分到多個線程執行,保證實例級別的事務一致性。
MySQL5.6 基于schema的并行復制
slave-parallel-type=DATABASE(不同庫的事務,沒有鎖沖突),并行復制的目的就是要讓slave盡可能的多線程跑起來,當然基于庫級別的多線程也是一種方式(不同庫的事務,沒有鎖沖突)。
**優點:**實現相對來說簡單,對用戶來說使用起來也簡單
缺點: 由于是基于庫的,那么并行的粒度非常粗,現在很多公司的架構是一庫一實例,針對這樣的架構,5.6的并行復制無能為力。當然還有就是主從事務的先后順序,對于5.6也是個大問題
MySQL 5.6版本開啟并行復制功能,那么SQL線程就變為了coordinator線程,coordinator線程主要負責以前兩部分的內容:
- 若判斷可以并行執行,那么選擇worker線程執行事務的二進制日志
- 若判斷不可以并行執行,如該操作是DDL,亦或者是事務跨schema操作,則等待所有的worker線程執行完成之后,再執行當前的日志
這意味著coordinator線程并不是僅將日志發送給worker線程,自己也可以回放日志,但是所有可以并行的操作交付由worker線程完成。coordinator線程與worker是典型的生產者與消費者模型。
上述機制實現了基于schema的并行復制存在兩個問題,首先是crash safe功能不好做,因為可能之后執行的事務由于并行復制的關系先完成執行,那么當發生crash的時候,這部分的處理邏輯是比較復雜的。從代碼上看,5.6這里引入了Low-Water-Mark標記來解決該問題,從設計上看(WL#5569),其是希望借助于日志的冪等性來解決該問題,不過5.6的二進制日志回放還不能實現冪等性。另一個最為關鍵的問題是這樣設計的并行復制效果并不高,如果用戶實例僅有一個庫,那么就無法實現并行回放,甚至性能會比原來的單線程更差。而單庫多表是比多庫多表更為常見的一種情形。
MySQL 5.7基于組提交的并行復制
MySQL 5.7才可稱為真正的并行復制,這其中最為主要的原因就是slave服務器的回放與主機是一致的即master服務器上是怎么并行執行的slave上就怎樣進行并行回放。不再有庫的并行復制限制,對于二進制日志格式也無特殊的要求(基于庫的并行復制也沒有要求)。從MySQL官方來看,其并行復制的原本計劃是支持表級的并行復制和行級的并行復制,行級的并行復制通過解析ROW格式的二進制日志的方式來完成,WL#4648。但是最終出現給小伙伴的確是在開發計劃中稱為:MTS: Prepared transactions slave parallel applier,可見:WL#6314。該并行復制的思想最早是由MariaDB的Kristain提出,并已在MariaDB 10中出現,相信很多選擇MariaDB的小伙伴最為看重的功能之一就是并行復制。
MySQL 5.7并行復制的思想簡單易懂,一言以蔽之:一個組提交的事務都是可以并行回放,因為這些事務都已進入到事務的prepare階段,則說明事務之間沒有任何沖突(否則就不可能提交)。
為了兼容MySQL 5.6基于庫的并行復制,5.7引入了新的變量slave-parallel-type,其可以配置的值有:
- DATABASE:默認值,基于庫的并行復制方式
- LOGICAL_CLOCK:基于組提交的并行復制方式
支持并行復制的GTID(5.7之后支持)
在MySQL 5.7版本中,其設計方式是將組提交的信息存放在GTID中。那么如果用戶沒有開啟GTID功能,即將參數gtid_mode設置為OFF,MySQL 5.7又引入了稱之為Anonymous_Gtid的二進制日志event類型,意味著在MySQL 5.7版本中即使不開啟GTID,每個事務開始前也是會存在一個Anonymous_Gtid,而這GTID中就存在著組提交的信息。
然而,通過上述的SHOW BINLOG EVENTS,我們并沒有發現有關組提交的任何信息。但是通過mysqlbinlog工具,用戶就能發現組提交的內部信息:
可以發現較之原來的二進制日志內容多了last_committed和sequence_number,last_committed表示事務提交的時候,上次事務提交的編號,如果事務具有相同的last_committed,表示這些事務都在一組內,可以進行并行的回放。例如上述last_committed為0的事務有6個,表示組提交時提交了6個事務,而這6個事務在從機是可以進行并行回放的。
總結
以上是生活随笔為你收集整理的MySQL的主从复制的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Crystal Reports 2008
- 下一篇: 一台电脑如何开俩虚拟机_虚拟机轻松实现一
