目錄
3.2 數據實時備份,當系統中某個節點發生故障時,可以方便的故障切換(主從切換)
7.1 Statement-base Replication (SBR)
一、概要
mysql從3.23版本開始提供複製功能,複製是將主庫的DDL和DML操作通過二進制日誌傳遞到複製服務器(從庫)上,然後從庫對這些日誌重新執行(重做),從而使得主庫和從庫保持數據一致。
1.1 mysql複製的優點
- 如果主庫出現問題,可以快速切換到從庫提供服務
- 可以在從庫執行查詢操作,降低主庫的訪問壓力。
- 可以在從庫進行備份,以免備份期間影響主庫的服務。
1.2 Mysql複製解決的問題
- 數據分佈 (Data distribution )
- 負載平衡(load balancing)
- 數據備份(Backups) ,保證數據安全
- 高可用性和容錯行(High availability and failover)
- 實現讀寫分離,緩解數據庫壓力
注意:由於mysql實現的異步複製,所以主庫和從庫數據之間存在一定的差異,在從庫執行查詢操作需要考慮這些數據的差異,一般只有更新不頻繁和對實時性要求不高的數據可以通過從庫查詢,實行要求高的仍要從主庫查詢。
二、MySQL 主從複製的概念
MySQL 主從複製是指數據可以從一個MySQL數據庫服務器主節點複製到一個或多個從節點。MySQL 默認採用異步複製方式,這樣從節點不用一直訪問主服務器來更新自己的數據,數據的更新可以在遠程連接上進行,從節點可以複製主數據庫中的所有數據庫或者特定的數據庫,或者特定的表。
三、MySQL 主從複製的主要用途
3.1 讀寫分離
在開發工作中,有時候會遇見某個sql 語句需要鎖表,導致暫時不能使用讀的服務,這樣就會影響現有業務,使用主從複製,讓主庫負責寫,從庫負責讀,這樣,即使主庫出現了鎖表的情景,通過讀從庫也可以保證業務的正常運作。
3.2 數據實時備份,當系統中某個節點發生故障時,可以方便的故障切換(主從切換)
3.3 高可用(HA)
3.4 架構擴展
隨着系統中業務訪問量的增大,如果是單機部署數據庫,就會導致I/O訪問頻率過高。有了主從複製,增加多個數據存儲節點,將負載分佈在多個從節點上,降低單機磁盤I/O訪問的頻率,提高單個機器的I/O性能。
四、MySQL 主從形式一主一從
4.1 一主多從
提高系統的讀性能
一主一從和一主多從是最常見的主從架構,實施起來簡單並且有效,不僅可以實現HA,而且還能讀寫分離,進而提升集羣的併發能力。
4.2 多主一從 (從5.7開始支持)
多主一從可以將多個mysql數據庫備份到一臺存儲性能比較好的服務器上。
4.3 雙主複製
雙主複製,也就是互做主從複製,每個master(主)既是master,又是另外一臺服務器的slave(從)。這樣任何一方所做的變更,都會通過複製應用到另外一方的數據庫中。
4.4 級聯複製
級聯複製模式下,部分slave的數據同步不連接主節點,而是連接從節點。因爲如果主節點有太多的從節點,就會損耗一部分性能用於replication(複製),那麼我們可以讓3~5個從節點連接主節點,其它從節點作爲二級或者三級與從節點連接,這樣不僅可以緩解主節點的壓力,並且對數據一致性沒有負面影響。級聯複製下從節點也要開啓binary log(bin-log)功能。
五、MySQL 主從複製的原理
MySQL主從複製涉及到三個線程,一個運行在主節點(log dump thread),其餘兩個(I/O thread, SQL thread)運行在從節點,如下圖所示:
5.1 主節點 log dump 線程
當從節點連接主節點時,主節點會爲其創建一個log dump 線程,用於發送和讀取bin-log的內容。在讀取bin-log中的操作時,log dump線程會對主節點上的bin-log加鎖,當讀取完成,在發送給從節點之前,鎖會被釋放。主節點會爲自己的每一個從節點創建一個log dump 線程。
5.2 從節點 I/O線程
當從節點上執行`start slave`命令之後,從節點會創建一個I/O線程用來連接主節點,請求主庫中更新的bin-log。I/O線程接收到主節點的blog dump進程發來的更新之後,保存在本地relay-log(中繼日誌)中。
5.3 從節點 SQL線程
SQL線程負責讀取relay-log中的內容,解析成具體的操作並執行,最終保證主從數據的一致性。
對於每一個主從連接,都需要這三個進程來完成。當主節點有多個從節點時,主節點會爲每一個當前連接的從節點建一個log dump 進程,而每個從節點都有自己的I/O進程,SQL進程。從節點用兩個線程將從主庫拉取更新和執行分成獨立的任務,這樣在執行同步數據任務的時候,不會降低讀操作的性能。比如,如果從節點沒有運行,此時I/O進程可以很快從主節點獲取更新,儘管SQL進程還沒有執行。如果在SQL進程執行之前從節點服務停止,至少I/O進程已經從主節點拉取到了最新的變更並且保存在本地relay日誌中,當服務再次起來之後,就可以完成數據的同步。
要實施複製,首先必須打開Master 端的binary log(bin-log)功能,否則無法實現。
因爲整個複製過程實際上就是Slave 從Master 端獲取該日誌然後再在自己身上完全順序的執行日誌中所記錄的各種操作。如下圖所示:
5.4 複製的基本過程
- 在從節點上執行sart slave命令開啓主從複製開關,開始進行主從複製。從節點上的I/O 進程連接主節點,並請求從指定日誌文件的指定位置(或者從最開始的日誌)之後的日誌內容;
- 主節點接收到來自從節點的I/O請求後,通過負責複製的I/O進程(log dump 線程)根據請求信息讀取指定日誌指定位置之後的日誌信息,返回給從節點。返回信息中除了日誌所包含的信息之外,還包括本次返回的信息的bin-log file 的以及bin-log position(bin-log中的下一個指定更新位置);
- 從節點的I/O進程接收到主節點發送過來的日誌內容、日誌文件及位置點後,將接收到的日誌內容更新到本機的relay-log(中繼日誌)的文件(Mysql-relay-bin.xxx)的最末端,並將讀取到的binary log(bin-log)文件名和位置保存到master-info 文件中,以便在下一次讀取的時候能夠清楚的告訴Master“我需要從某個bin-log 的哪個位置開始往後的日誌內容,請發給我”;
- Slave 的 SQL線程檢測到relay-log 中新增加了內容後,會將relay-log的內容解析成在主節點上實際執行過SQL語句,然後在本數據庫中按照解析出來的順序執行,並在relay-log.info中記錄當前應用中繼日誌的文件名和位置點。
六、MySQL 主從複製的模式
MySQL 主從複製默認是異步的模式。MySQL增刪改操作會全部記錄在bin-log(binary log)中,當slave節點連接master時,會主動從master處獲取最新的bin-log文件。並把bin-log存儲到本地的relay-log中,然後去執行relay-log的更新內容。
6.1 異步模式(mysql async-mode)
異步模式如下圖所示,這種模式下,主節點不會主動推送bin-log到從節點,主庫在執行完客戶端提交的事務後會立即將結果返給給客戶端,並不關心從庫是否已經接收並處理,這樣就會有一個問題,主節點如果崩潰掉了,此時主節點上已經提交的事務可能並沒有傳到從節點上,如果此時,強行將從提升爲主,可能導致新主節點上的數據不完整。
6.2 半同步模式(mysql semi-sync)
介於異步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay-log中才返回成功信息給客戶端(只能保證主庫的bin-log至少傳輸到了一個從節點上,但並不能保證從節點將此事務執行更新到db中),否則需要等待直到超時時間然後切換成異步模式再提交。相對於異步複製,半同步複製提高了數據的安全性,一定程度的保證了數據能成功備份到從庫,同時它也造成了一定程度的延遲,但是比全同步模式延遲要低,這個延遲最少是一個TCP/IP往返的時間。所以,半同步複製最好在低延時的網絡中使用。如下圖所示:
半同步模式不是mysql內置的,從mysql 5.5開始集成,需要master 和slave 安裝插件開啓半同步模式。
6.3 全同步模式
指當主庫執行完一個事務,然後所有的從庫都複製了該事務併成功執行完才返回成功信息給客戶端。因爲需要等待所有從庫執行完該事務才能返回成功信息,所以全同步複製的性能必然會收到嚴重的影響。
6.4 異步模式,全同步模式,半同步模式的對比圖
6.5 GTID複製模式
在傳統的複製裏面,當發生故障,需要主從切換,需要找到bin-log和pos點(指從庫更新到了主庫bin-log的哪個位置,這個位置之前都已經更顯完畢,這個位置之後未更新),然後將主節點指向新的主節點,相對來說比較麻煩,也容易出錯。在MySQL 5.6裏面,不用再找bin-log和pos點,我們只需要知道主節點的ip,端口,以及賬號密碼就行,因爲複製是自動的,MySQL會通過內部機制GTID自動找點同步。
基於GTID的複製是MySQL 5.6後新增的複製方式.
GTID (global transaction identifier) 即全局事務ID, 保證了在每個在主庫上提交的事務在集羣中有一個唯一的ID.
6.5.1 GTID複製原理
在原來基於日誌的複製中, 從庫需要告知主庫要從哪個偏移量進行增量同步, 如果指定錯誤會造成數據的遺漏, 從而造成數據的不一致.
而基於GTID的複製中, 從庫會告知主庫已經執行的事務的GTID的值, 然後主庫會將所有未執行的事務的GTID的列表返回給從庫. 並且可以保證同一個事務只在指定的從庫執行一次.通過全局的事務ID確定從庫要執行的事務的方式代替了以前需要用bin-log和pos點確定從庫要執行的事務的方式。
GTID是由server_uuid和事物id組成,格式爲:GTID=server_uuid:transaction_id。server_uuid是在數據庫啓動過程中自動生成,每臺機器的server-uuid不一樣。uuid存放在數據目錄的auto.conf文件中,而transaction_id就是事務提交時系統順序分配的一個不會重複的序列號。
主節點更新數據時,會在事務前產生GTID,一起記錄到bin-log日誌中。從節點的I/O線程將變更的bin-log,寫入到本地的relay-log中。SQL線程從relay-log中獲取GTID,然後對比本地bin-log是否有記錄(所以MySQL從節點必須要開啓binary-log)。如果有記錄,說明該GTID的事務已經執行,從節點會忽略。如果沒有記錄,從節點就會從relay-log中執行該GTID的事務,並記錄到binlog。在解析過程中會判斷是否有主鍵,如果沒有就用二級索引,如果有就用全部掃描。
6.5.2 GTID的好處
- GTID使用master_auto_position=1代替了binlog和position號的主從複製搭建方式,相比binlog和position方式更容易搭建主從複製。
- GTID方便實現主從之間的failover(主從切換),不用一步一步的去查找position和binlog文件。
6.5.3 GTID模式複製侷限性
- 不能使用create table table_name select * from table_name模式的語句
- 在一個事務中既包含事務表的操作又包含非事務表
- 不支持CREATE TEMPORARY TABLE or DROP TEMPORARY TABLE語句操作
- 使用GTID複製從庫跳過錯誤時,不支持sql_slave_skip_counter參數的語法
6.6 多線程複製
多線程複製(基於庫),在MySQL 5.6以前的版本,slave的複製是單線程的,而master是併發寫入的,所以延時是避免不了的。唯一有效的方法是把多個庫放在多臺slave,這樣又有點浪費服務器。在MySQL 5.6裏面,我們可以把多個表放在多個庫,這樣就可以使用多線程複製。
但 5.6 中的每個線程只能處理一個數據庫,所以如果只有一個數據庫,或者絕大多數寫操作都是集中在某一個數據庫的,那麼這個“多線程複製”就不能充分發揮作用了
Mysql 5.7 對 “多線程複製” 進行了改善,可以按照邏輯時鐘的方式來分配線程,大大提高了複製性能
七、MySQL主從複製的方式
MySQL 主從複製有三種方式:基於SQL語句的複製(statement-based replication,SBR),基於行的複製(row-based replication,RBR),混合模式複製(mixed-based replication,MBR)。對應的bin-log文件的格式也有三種:STATEMENT, ROW, MIXED。
7.1 Statement-base Replication (SBR)
就是記錄sql語句在bin-log中,Mysql 5.1.4 及之前的版本都是使用的這種複製格式。優點是只需要記錄會修改數據的sql語句到bin-log中,減少了bin-log日質量,節約I/O,提高性能。缺點是在某些情況下,會導致主從節點中數據不一致(比如sleep(),now()等)。
7.2 Row-based Relication(RBR)
mysql master將SQL語句分解爲基於Row更改的語句並記錄在bin-log中,也就是隻記錄哪條數據被修改了,修改成什麼樣。優點是不會出現某些特定情況下的存儲過程、或者函數、或者trigger的調用或者觸發無法被正確複製的問題。缺點是會產生大量的日誌,尤其是修改table的時候會讓日誌暴增,同時增加bin-log同步時間。也不能通過bin-log解析獲取執行過的sql語句,只能看到發生的data變更。
7.3 Mixed-format Replication(MBR)
MySQL NDB cluster 7.3 和7.4 使用的MBR。是以上兩種模式的混合,對於一般的複製使用STATEMENT模式保存到bin-log,對於STATEMENT模式無法複製的操作則使用ROW模式來保存,MySQL會根據執行的SQL語句選擇日誌保存方式。
八、總結
Mysql 主從複製是mysql 高可用,高性能的基礎,有了這個基礎,mysql 的部署會變得簡單、靈活並且具有多樣性,從而可以根據不同的業務場景做出靈活的調整。
參考資料:《深入淺出MySQL開發、維護與管理》唐漢明著