MySQL-主从架构探索
文章目錄
- 生猛干貨
- 官方文檔
- 為什么要用主從方案
- 常見(jiàn)的主從方案
- 一主一從 M-S
- 一主多從 M-S-S-S
- 多主一從 M-M-M-S (5.7開(kāi)始支持)
- 使用場(chǎng)景
- 一主多級(jí)從
- 雙主 M-M
- 環(huán)形主從(復(fù)制)S-S-S-S
- 使用場(chǎng)景
- MySQL安裝
- 主從復(fù)制的概念
- 主從復(fù)制的兩種方案
- 主從架構(gòu)的架構(gòu)圖解析
- MySQL主從復(fù)制涉及到三個(gè)線程
- 主節(jié)點(diǎn) binary log dump 線程
- 從節(jié)點(diǎn)-I/O線程
- 從節(jié)點(diǎn)-SQL線程
- MySQL 主從復(fù)制的過(guò)程
- MySQL 主從復(fù)制模式
- 異步模式(mysql async-mode)
- 半同步模式(mysql semi-sync)
- 全同步模式(mysql fully synchronized)
- binlog記錄格式
- GTID復(fù)制模式
- MySQL 主從復(fù)制主要用途
- MySQL復(fù)制性能優(yōu)化
- 如何在MySQL5.7中配置多線程復(fù)制
- MySQL主從復(fù)制無(wú)法解決的問(wèn)題
- 搞定MySQL
生猛干貨
帶你搞定MySQL實(shí)戰(zhàn),輕松對(duì)應(yīng)海量業(yè)務(wù)處理及高并發(fā)需求,從容應(yīng)對(duì)大場(chǎng)面試
官方文檔
https://dev.mysql.com/doc/
如果英文不好的話,可以參考 searchdoc 翻譯的中文版本
http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/index.com.coder114.cn.html
為什么要用主從方案
可以從以下的幾個(gè)方面來(lái)考慮
- 如果主服務(wù)器出現(xiàn)問(wèn)題,可以快速切換到從服務(wù)器提供的服務(wù) 。 (如果做了讀寫(xiě)分離的話,主庫(kù)掛了,起碼還能提供查詢服務(wù)。 如果又做了高可用的話,從服務(wù)可以提升為主節(jié)點(diǎn)。 )
- 可以在從服務(wù)器上執(zhí)行查詢操作,降低主服務(wù)器的訪問(wèn)壓力
- 可以在從服務(wù)器上執(zhí)行備份,以避免備份期間影響主服務(wù)器的服務(wù)
常見(jiàn)的主從方案
每個(gè)方案都有其適用的場(chǎng)景,沒(méi)有通用的放之四海而皆準(zhǔn)的方案。根據(jù)自己的業(yè)務(wù)選擇合理的方案。
一主一從 M-S
最簡(jiǎn)單的主從方案
一主多從 M-S-S-S
一主一從和一主多從是最常見(jiàn)的主從架構(gòu),實(shí)施起來(lái)簡(jiǎn)有效,不僅可以實(shí)現(xiàn)HA,而且還能讀寫(xiě)分離,進(jìn)而提升集群的并發(fā)能力。
多主一從 M-M-M-S (5.7開(kāi)始支持)
多主一從可以將多個(gè)mysql數(shù)據(jù)庫(kù)備份到一臺(tái)存儲(chǔ)性能比較好的服務(wù)器上。
使用場(chǎng)景
舉個(gè)例子 master節(jié)點(diǎn)是各個(gè)分公司的庫(kù), slave節(jié)點(diǎn)是集團(tuán)公司的庫(kù)。 數(shù)據(jù)同步至集團(tuán)slave節(jié)點(diǎn)。
集團(tuán)公司要?jiǎng)討B(tài)的掌握子公司的財(cái)務(wù)狀況,集團(tuán)每個(gè)月要進(jìn)行匯總,這個(gè)時(shí)候各個(gè)子公司(master節(jié)點(diǎn))把數(shù)據(jù)匯總到集團(tuán)公司(slave節(jié)點(diǎn)),這樣是不是方便來(lái)集團(tuán)公司匯總查看了?
一主多級(jí)從
級(jí)聯(lián)復(fù)制模式下,部分slave的數(shù)據(jù)同步不連接主節(jié)點(diǎn),而是連接從節(jié)點(diǎn)。
因?yàn)槿绻鞴?jié)點(diǎn)有太多的從節(jié)點(diǎn),就會(huì)損耗一部分性能用于replication,那么我們可以讓3~5個(gè)從節(jié)點(diǎn)連接主節(jié)點(diǎn),其它從節(jié)點(diǎn)作為二級(jí)或者三級(jí)與從節(jié)點(diǎn)連接,這樣不僅可以緩解主節(jié)點(diǎn)的壓力,并且對(duì)數(shù)據(jù)一致性沒(méi)有負(fù)面影響。
雙主 M-M
雙主結(jié)構(gòu),相互讀寫(xiě)復(fù)制。
雙主復(fù)制,也就是互做主從復(fù)制,每個(gè)master既是master,又是另外一臺(tái)服務(wù)器的slave。這樣任何一方所做的變更,都會(huì)通過(guò)復(fù)制應(yīng)用到另外一方的數(shù)據(jù)庫(kù)中。
我們常用的M-M-M 高可用的方案就是基于這個(gè)來(lái)做的。
環(huán)形主從(復(fù)制)S-S-S-S
使用場(chǎng)景
比較特殊的一種場(chǎng)景
舉個(gè)例子: 各個(gè)分公司之間有些數(shù)據(jù)是共享的,任何一個(gè)分公司的數(shù)據(jù)的變化都要通知到其他分公司,這個(gè)時(shí)候使用這種閉環(huán)的方案比較合適。
MySQL安裝
MySQL-CentOS7通過(guò)YUM安裝MySQL5.7.29
主從復(fù)制的概念
MYSQL的主從復(fù)制主要是說(shuō)數(shù)據(jù)可以從一個(gè)MySQL數(shù)據(jù)庫(kù)服務(wù)器主節(jié)點(diǎn)復(fù)制到一個(gè)或多個(gè)從節(jié)點(diǎn)。
MySQL 默認(rèn)采用異步復(fù)制方式。
這樣從節(jié)點(diǎn)不用一直訪問(wèn)主服務(wù)器來(lái)更新自己的數(shù)據(jù),數(shù)據(jù)的更新可以在遠(yuǎn)程連接上進(jìn)行,從節(jié)點(diǎn)可以復(fù)制主數(shù)據(jù)庫(kù)中的所有數(shù)據(jù)庫(kù)或者特定的數(shù)據(jù)庫(kù),或者特定的表。
主從復(fù)制的兩種方案
目前來(lái)說(shuō),MYSQL提供了兩種方式來(lái)實(shí)現(xiàn)主從復(fù)制
我們這里重點(diǎn)來(lái)討論基于bin log的主從復(fù)制
主從架構(gòu)的架構(gòu)圖解析
MySQL主從復(fù)制涉及到三個(gè)線程
MySQL主從復(fù)制涉及到三個(gè)線程
- 主節(jié)點(diǎn)(log dump thread)
- 其余兩個(gè)(I/O thread, SQL thread)運(yùn)行在從節(jié)點(diǎn)
主節(jié)點(diǎn) binary log dump 線程
當(dāng)從節(jié)點(diǎn)連接主節(jié)點(diǎn)時(shí),主節(jié)點(diǎn)會(huì)創(chuàng)建一個(gè)binlog dump 線程,用于發(fā)送bin-log的內(nèi)容。
從節(jié)點(diǎn)-I/O線程
當(dāng)從節(jié)點(diǎn)上執(zhí)行start slave命令之后,從節(jié)點(diǎn)會(huì)創(chuàng)建一個(gè)I/O線程用來(lái)連接主節(jié)點(diǎn),請(qǐng)求主庫(kù)中更新的bin-log。I/O線程接收到主節(jié)點(diǎn)binlog dump 進(jìn)程發(fā)來(lái)的更新之后,保存在本地relay-log中。
從節(jié)點(diǎn)-SQL線程
SQL線程負(fù)責(zé)讀取relay log中的內(nèi)容,解析成具體的操作并執(zhí)行,最終保證主從數(shù)據(jù)的一致性。
MySQL 主從復(fù)制的過(guò)程
對(duì)于每一個(gè)主從連接,都需要三個(gè)線程來(lái)完成。
當(dāng)主節(jié)點(diǎn)有多個(gè)從節(jié)點(diǎn)時(shí),主節(jié)點(diǎn)會(huì)為每一個(gè)當(dāng)前連接的從節(jié)點(diǎn)建一個(gè)binary log dump 進(jìn)程,而每個(gè)從節(jié)點(diǎn)都有自己的I/O進(jìn)程,SQL進(jìn)程。
從節(jié)點(diǎn)用兩個(gè)線程將從主庫(kù)拉取更新和執(zhí)行分成獨(dú)立的任務(wù),這樣在執(zhí)行同步數(shù)據(jù)任務(wù)的時(shí)候,不會(huì)降低讀操作的性能。比如,如果從節(jié)點(diǎn)沒(méi)有運(yùn)行,此時(shí)I/O進(jìn)程可以很快從主節(jié)點(diǎn)獲取更新,盡管SQL進(jìn)程還沒(méi)有執(zhí)行。如果在SQL進(jìn)程執(zhí)行之前從節(jié)點(diǎn)服務(wù)停止,至少I/O進(jìn)程已經(jīng)從主節(jié)點(diǎn)拉取到了最新的變更并且保存在本地relay日志中,當(dāng)服務(wù)再次起來(lái)之后,就可以完成數(shù)據(jù)的同步。
要實(shí)施復(fù)制,首先必須打開(kāi)Master 端的binary log(bin-log)功能,否則無(wú)法實(shí)現(xiàn)。 因?yàn)檎麄€(gè)復(fù)制過(guò)程實(shí)際上就是Slave 從Master 端獲取該日志然后再在自己身上完全順序的執(zhí)行日志中所記錄的各種操作。
- 從節(jié)點(diǎn)(Slave )上的I/O 進(jìn)程連接主節(jié)點(diǎn)(Master),并請(qǐng)求從指定日志文件的指定位置(或者從最開(kāi)始的日志)之后的日志內(nèi)容;
- 主節(jié)點(diǎn)(Master)接收到來(lái)自從節(jié)點(diǎn)(Slave )的I/O請(qǐng)求后,通過(guò)負(fù)責(zé)復(fù)制的I/O進(jìn)程根據(jù)請(qǐng)求信息讀取指定日志指定位置之后的日志信息,返回給從節(jié)點(diǎn)。返回信息中除了日志所包含的信息之外,還包括本次返回的信息的bin-log file 的以及bin-log position;從節(jié)點(diǎn)的I/O進(jìn)程接收到內(nèi)容后,將接收到的日志內(nèi)容更新到本機(jī)的relay log中,并將讀取到的binary log文件名和位置保存到master-info 文件中,以便在下一次讀取的時(shí)候能夠清楚的告訴Master“我需要從某個(gè)bin-log 的哪個(gè)位置開(kāi)始往后的日志內(nèi)容,請(qǐng)發(fā)給我”;
- Slave 的 SQL線程檢測(cè)到relay-log 中新增加了內(nèi)容后,會(huì)將relay-log的內(nèi)容解析成在主節(jié)點(diǎn)上實(shí)際執(zhí)行過(guò)的操作,并在本數(shù)據(jù)庫(kù)中執(zhí)行。
MySQL 主從復(fù)制模式
MySQL 主從復(fù)制默認(rèn)是異步的模式。MySQL增刪改操作會(huì)全部記錄在binary log中,當(dāng)slave節(jié)點(diǎn)連接master時(shí),會(huì)主動(dòng)從master處獲取最新的bin log文件
異步模式(mysql async-mode)
主節(jié)點(diǎn)不會(huì)主動(dòng)push bin log到從節(jié)點(diǎn),這樣有可能導(dǎo)致failover的情況下,也許從節(jié)點(diǎn)沒(méi)有即時(shí)地將最新的bin log同步到本地,但效率高。
半同步模式(mysql semi-sync)
主節(jié)點(diǎn)只需要接收到其中一臺(tái)從節(jié)點(diǎn)的返回信息,就會(huì)commit;否則需要等待直到超時(shí)時(shí)間然后切換成異步模式再提交;這樣做的目的可以使主從數(shù)據(jù)庫(kù)的數(shù)據(jù)延遲縮小,可以提高數(shù)據(jù)安全性,確保了事務(wù)提交后,binlog至少傳輸?shù)搅艘粋€(gè)從節(jié)點(diǎn)上,不能保證從節(jié)點(diǎn)將此事務(wù)更新到db中。性能上會(huì)有一定的降低,響應(yīng)時(shí)間會(huì)變長(zhǎng).
半同步模式不是mysql內(nèi)置的,從mysql 5.5開(kāi)始集成,需要master 和slave 安裝插件開(kāi)啟半同步模式。
全同步模式(mysql fully synchronized)
主節(jié)點(diǎn)和從節(jié)點(diǎn)全部執(zhí)行了commit并確認(rèn)才會(huì)向客戶端返回成功
binlog記錄格式
MySQL 主從復(fù)制有三種方式:
基于SQL語(yǔ)句的復(fù)制(statement-based replication,SBR),
基于行的復(fù)制(row-based replication,RBR),
混合模式復(fù)制(mixed-based replication,MBR)。
對(duì)應(yīng)的binlog文件的格式也有三種:STATEMENT,ROW,MIXED。
-
Statement-base Replication (SBR)就是記錄sql語(yǔ)句在bin log中,Mysql 5.1.4
及之前的版本都是使用的這種復(fù)制格式。優(yōu)點(diǎn)是只需要記錄會(huì)修改數(shù)據(jù)的sql語(yǔ)句到binlog中,減少了binlog日質(zhì)量,節(jié)約I/O,提高性能。缺點(diǎn)是在某些情況下,會(huì)導(dǎo)致主從節(jié)點(diǎn)中數(shù)據(jù)不一致(比如sleep(),now()等)。 -
Row-based Relication(RBR)是mysql master將SQL語(yǔ)句分解為基于Row更改的語(yǔ)句并記錄在bin log中,也就是只記錄哪條數(shù)據(jù)被修改了,修改成什么樣。優(yōu)點(diǎn)是不會(huì)出現(xiàn)某些特定情況下的存儲(chǔ)過(guò)程、或者函數(shù)、或者trigger的調(diào)用或者觸發(fā)無(wú)法被正確復(fù)制的問(wèn)題。缺點(diǎn)是會(huì)產(chǎn)生大量的日志,尤其是修改table的時(shí)候會(huì)讓日志暴增,同時(shí)增加bin log同步時(shí)間。也不能通過(guò)bin log解析獲取執(zhí)行過(guò)的sql語(yǔ)句,只能看到發(fā)生的data變更。
-
Mixed-format Replication(MBR),MySQL NDB cluster 7.3 和7.4 使用的MBR。是以上兩種模式的混合,對(duì)于一般的復(fù)制使用STATEMENT模式保存到binlog,對(duì)于STATEMENT模式無(wú)法復(fù)制的操作則使用ROW模式來(lái)保存,MySQL會(huì)根據(jù)執(zhí)行的SQL語(yǔ)句選擇日志保存方式。
MySQL 5.7.6之前默認(rèn)為STATEMENT模式。MySQL 5.7.7之后默認(rèn)為ROW模式. 這個(gè)參數(shù)主要影響主從復(fù)制。
GTID復(fù)制模式
GTID底層也是基于bin log 。
1、全局事物標(biāo)識(shí):global transaction identifieds。
2、GTID事物是全局唯一性的,且一個(gè)事務(wù)對(duì)應(yīng)一個(gè)GTID。
3、一個(gè)GTID在一個(gè)服務(wù)器上只執(zhí)行一次,避免重復(fù)執(zhí)行導(dǎo)致數(shù)據(jù)混亂或者主從不一致。
4、GTID用來(lái)代替classic的復(fù)制方法,不在使用binlog+pos開(kāi)啟復(fù)制。而是使用master_auto_postion=1的方式自動(dòng)匹配GTID斷點(diǎn)進(jìn)行復(fù)制。
5、MySQL-5.6.5開(kāi)始支持的,MySQL-5.6.10后開(kāi)始完善。
6、在傳統(tǒng)的slave端,binlog是不用開(kāi)啟的,但是在GTID中,slave端的binlog是必須開(kāi)啟的,目的是記錄執(zhí)行過(guò)的GTID(強(qiáng)制)
基于GTID復(fù)制實(shí)現(xiàn)的工作原理
-
主節(jié)點(diǎn)更新數(shù)據(jù)時(shí),會(huì)在事務(wù)前產(chǎn)生GTID,一起記錄到binlog日志中。
-
從節(jié)點(diǎn)的I/O線程將變更的bin log,寫(xiě)入到本地的relay log中。
-
SQL線程從relay log中獲取GTID,然后對(duì)比本地binlog是否有記錄(所以MySQL從節(jié)點(diǎn)必須要開(kāi)啟binary log)。
-
如果有記錄,說(shuō)明該GTID的事務(wù)已經(jīng)執(zhí)行,從節(jié)點(diǎn)會(huì)忽略。
-
如果沒(méi)有記錄,從節(jié)點(diǎn)就會(huì)從relay log中執(zhí)行該GTID的事務(wù),并記錄到bin log。
-
在解析過(guò)程中會(huì)判斷是否有主鍵,如果沒(méi)有就用二級(jí)索引,如果有就用全部掃描。
MySQL 主從復(fù)制主要用途
-
讀寫(xiě)分離 : 有時(shí)候會(huì)遇見(jiàn)某個(gè)sql 語(yǔ)句需要鎖表,導(dǎo)致暫時(shí)不能使用讀的服務(wù),這樣就會(huì)影響現(xiàn)有業(yè)務(wù),使用主從復(fù)制,讓主庫(kù)負(fù)責(zé)寫(xiě),從庫(kù)負(fù)責(zé)讀,這樣,即使主庫(kù)出現(xiàn)了鎖表的情景,通過(guò)讀從庫(kù)也可以保證業(yè)務(wù)的正常運(yùn)作。
-
數(shù)據(jù)實(shí)時(shí)備 : 當(dāng)系統(tǒng)中某個(gè)節(jié)點(diǎn)發(fā)生故障時(shí),可以方便的故障切換
-
高可用HA
-
架構(gòu)擴(kuò)展: 隨著系統(tǒng)中業(yè)務(wù)訪問(wèn)量的增大,如果是單機(jī)部署數(shù)據(jù)庫(kù),就會(huì)導(dǎo)致I/O訪問(wèn)頻率過(guò)高。有了主從復(fù)制,增加多個(gè)數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn),將負(fù)載分布在多個(gè)從節(jié)點(diǎn)上,降低單機(jī)磁盤(pán)I/O訪問(wèn)的頻率,提高單個(gè)機(jī)器的I/O性能。
MySQL復(fù)制性能優(yōu)化
影響主從延遲的因素
- 主庫(kù)寫(xiě)入二進(jìn)制日志的時(shí)間 ------> 控制主庫(kù)的事務(wù)大小,分割大事務(wù)
- 二進(jìn)制日志傳輸?shù)臅r(shí)間 ------> 使用mixed日志格式 或者 使用row,但要set binlog_row_image=minimal;
- 默認(rèn)情況下從庫(kù)只有一個(gè)SQL線程,主庫(kù)上并發(fā)修改但到了從庫(kù)變成了一個(gè)線程串行 -----> 使用多線程復(fù)制 (5.6提供的功能) ,在mysql中可以按照邏輯時(shí)鐘的方式來(lái)分配SQL線程
如何在MySQL5.7中配置多線程復(fù)制
在從服務(wù)器上 配置
[root@artisan binlog]# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 51 Server version: 5.7.29-log MySQL Community Server (GPL) ... .... .....mysql> mysql> stop slave; Query OK, 0 rows affected (0.01 sec)mysql> set global slave_parallel_type='logical_clock'; Query OK, 0 rows affected (0.03 sec)mysql> set global slave_parallel_workers=4; # 設(shè)置4個(gè)SQL線程 Query OK, 0 rows affected (0.04 sec)mysql> start slave; Query OK, 0 rows affected (0.36 sec)mysql>查看
mysql> show processlist \G; *************************** 1. row ***************************Id: 21User: rootHost: localhostdb: NULL Command: QueryTime: 0State: startingInfo: show processlist *************************** 2. row ***************************Id: 22User: system userHost: db: NULL Command: ConnectTime: 126State: Waiting for master to send eventInfo: NULL *************************** 3. row ***************************Id: 23User: system userHost: db: NULL Command: ConnectTime: 126State: Slave has read all relay log; waiting for more updatesInfo: NULL *************************** 4. row ***************************Id: 24User: system userHost: db: NULL Command: ConnectTime: 126State: Waiting for an event from CoordinatorInfo: NULL *************************** 5. row ***************************Id: 25User: system userHost: db: NULL Command: ConnectTime: 126State: Waiting for an event from CoordinatorInfo: NULL *************************** 6. row ***************************Id: 26User: system userHost: db: NULL Command: ConnectTime: 126State: Waiting for an event from CoordinatorInfo: NULL *************************** 7. row ***************************Id: 27User: system userHost: db: NULL Command: ConnectTime: 126State: Waiting for an event from CoordinatorInfo: NULL 7 rows in set (0.00 sec)ERROR: No query specifiedmysql>MySQL主從復(fù)制無(wú)法解決的問(wèn)題
- 無(wú)法分擔(dān)主庫(kù)的寫(xiě)壓力 ---->分庫(kù)分表
- 無(wú)法提供讀寫(xiě)分離的功能
- 無(wú)法進(jìn)行自動(dòng)故障轉(zhuǎn)移及主從切換—> MMM或者 MHA(推薦)
搞定MySQL
總結(jié)
以上是生活随笔為你收集整理的MySQL-主从架构探索的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 白话Elasticsearch73_ES
- 下一篇: MySQL-CentOS7通过YUM安装