本文探討了MySQL主從復(fù)制的工作原理,包括Master和Slave之間的IO線程和SQL線程。主從同步是異步過(guò)程,Master通過(guò)IO線程請(qǐng)求 slave,slave通過(guò)IO線程接收 master 的bin-log日志,最后mast...
本文用docker的方式做MySQL主從試驗(yàn),方便理解原理,生產(chǎn)環(huán)境不建議使用docker部署數(shù)據(jù)庫(kù)。
MySQL主從復(fù)制的用途:確保數(shù)據(jù)安全,做數(shù)據(jù)的熱備,作為后備數(shù)據(jù)庫(kù),主數(shù)據(jù)庫(kù)服務(wù)器故障后,可切換到從數(shù)據(jù)庫(kù)繼續(xù)工作,避免數(shù)據(jù)的丟失。
MySQL主從復(fù)制的工作原理:MySQL主從數(shù)據(jù)同步是一個(gè)異步復(fù)制的過(guò)程,要實(shí)現(xiàn)復(fù)制首先需要在master上開(kāi)啟bin-log日志功能,bin-log日志用于記錄在Master庫(kù)中執(zhí)行的增、刪、修改、更新操作的sql語(yǔ)句。整個(gè)過(guò)程需要開(kāi)啟3個(gè)線程,分別是Master開(kāi)啟IO線程,Slave開(kāi)啟IO線程和SQL線程,
具體主從同步原理詳解如下:(也可以跳過(guò)這段廢話)qSlave上執(zhí)行slave start,Slave IO線程會(huì)通過(guò)在Master創(chuàng)建的授權(quán)用戶(hù)連接上至Master,并請(qǐng)求master從指定的文件和位置之后發(fā)送bin-log日志內(nèi)容;qMaster接收到來(lái)自slave IO線程的請(qǐng)求后,master IO線程根據(jù)slave發(fā)送的指定bin-log日志position點(diǎn)之后的內(nèi)容,然后返回給slave的IO線程。q返回的信息中除了bin-log日志內(nèi)容外,還有master最新的binlog文件名以及在binlog中的下一個(gè)指定更新position點(diǎn);qSlave IO線程接收到信息后,將接收到的日志內(nèi)容依次添加到Slave端的relay-log文件的最末端,并將讀取到的Master端的 bin-log的文件名和position點(diǎn)記錄到master.info文件中,以便在下一次讀取的時(shí)候能告知master從響應(yīng)的bin-log文件名及最后一個(gè)position點(diǎn)開(kāi)始發(fā)起請(qǐng)求;qSlave Sql線程檢測(cè)到relay-log中內(nèi)容有更新,會(huì)立刻解析relay-log的內(nèi)容成在Master真實(shí)執(zhí)行時(shí)候的那些可執(zhí)行的SQL語(yǔ)句,將解析的SQL語(yǔ)句并在Slave里執(zhí)行,執(zhí)行成功后,Master庫(kù)與Slave庫(kù)保持?jǐn)?shù)據(jù)一致。
MySQL主從復(fù)制實(shí)施注意事項(xiàng):主從服務(wù)器操作系統(tǒng)版本和位數(shù)一致;Master 和 Slave 數(shù)據(jù)庫(kù)的版本要一致;Master 和 Slave 數(shù)據(jù)庫(kù)中的數(shù)據(jù)要一致;Master 開(kāi)啟二進(jìn)制日志,Master 和 Slave 的 server_id 在局域網(wǎng)內(nèi)必須唯一。
MySQL主從復(fù)制結(jié)構(gòu)圖:
MySQL主從復(fù)制實(shí)戰(zhàn):
由于我電腦硬件配置低,無(wú)法跑2個(gè)虛擬機(jī),本實(shí)驗(yàn)用docker容器的方法:
環(huán)境搭建:docker pull mysql8.0鏡像:
docker pull mysql:8.0
docker run --name master -p8888:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0
分別測(cè)試登陸master和slave
mysql -u root -p123456 -P 8888 -h 127.0.0.1
mysql -u root -p123456 -P 9999 -h 127.0.0.1
復(fù)制容器里的my.cnf文件到宿主機(jī)當(dāng)前位置:
docker cp master:/etc/my.cnf ./
在my.cnf文件中[mysqld]段中加入如下代碼,cp回master容器原位置,重啟MYSQL服務(wù):server-id = 1 log-bin = mysql-bin
登錄master數(shù)據(jù)庫(kù),創(chuàng)建tongbu用戶(hù)及密碼并設(shè)置權(quán)限,執(zhí)行如下命令,查看bin-log文件及position點(diǎn):
CREATE USER 'tongbu'@'%' IDENTIFIED WITH mysql_native_password BY '123456';GRANT REPLICATION SLAVE ON *.* TO 'tongbu'@'%';show master status;
修改my.cnf文件,在[mysqld]段中加入如下代碼,cp回slave容器原位置,重啟MYSQL服務(wù):server-id = 2
Slave指定Master IP、用戶(hù)名、密碼、bin-log文件名( binlog.000003)及position(656),代碼如下:這里重點(diǎn)注意,因?yàn)槭怯萌萜髯龅膶?shí)驗(yàn)環(huán)境,要注意以下參數(shù)master_host='192.168.101.6',master_port=8888
change master to master_host='192.168.101.6',master_port=8888,master_user='tongbu',master_password='123456',master_log_file='mysql-bin.000004',master_log_pos=157;
在slave啟動(dòng)slave start,并執(zhí)行show slave status\G查看Mysql主從狀態(tài):show slave status\G;
#后面要加\G,則看起來(lái)很亂。
#要確保以下兩個(gè)地方顯示是Yes,如果不是Yes,需要檢查前面的步驟是否有錯(cuò)誤的地方;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
#如果顯示Slave_IO_Running:Connecting 的問(wèn)題,要從以下幾點(diǎn)查找:
#網(wǎng)絡(luò)不通、防火墻端口未開(kāi)放、mysql賬戶(hù)密碼錯(cuò)誤、mysql主從機(jī)配置文件寫(xiě)錯(cuò)、配置從機(jī)連接語(yǔ)法錯(cuò)誤、主機(jī)未開(kāi)放賬戶(hù)連接權(quán)限;
#例如本次實(shí)驗(yàn)因?yàn)闆](méi)注意容器的問(wèn)題,master_host='192.168.101.6',寫(xiě)成了127.0.0.1導(dǎo)致一直無(wú)法連接。
測(cè)試在master上創(chuàng)建一個(gè)數(shù)據(jù)庫(kù):
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> create database test_db;
Query OK, 1 row affected (0.03 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test_db |
+--------------------+
5 rows in set (0.00 sec)
在slave上查看是否同步過(guò)來(lái):
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test_db |
+--------------------+
5 rows in set (0.00 sec)
mysql>
可以看到,測(cè)試增加的test_db已經(jīng)自動(dòng)同步過(guò)來(lái),主從復(fù)制實(shí)驗(yàn)完成。
再做個(gè)試驗(yàn):構(gòu)建MySQL主主復(fù)制,實(shí)現(xiàn)在主庫(kù)操作增刪改,從庫(kù)能夠同步,在從庫(kù)操作增刪改,主庫(kù)也能同步數(shù)據(jù)。MySQL主主復(fù)制是指兩臺(tái)機(jī)器(master和slave)互為主從。
搭建MySQL主主復(fù)制環(huán)境:?jiǎn)?dòng)兩個(gè)MySQL8.0容器,name分別為node001(端口3333),node002(端口4444):
docker run --name node001 -p3333:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0
docker run --name node002 -p4444:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0
利用docker cp node001/node002:/etc/my.cnf,復(fù)制出my.cnf配置文件并修改后利用docker cp my.cnf node001/node002:/etc/傳回容器內(nèi)部,修改如下:
在node001的[mysqld]字段上添加
server-id = 1
log_bin = mysql-bin
在node002的[mysqld]字段上添加
server-id = 2
log_bin = mysql-bin
重啟兩個(gè)容器(達(dá)到重啟mysql服務(wù)的作用):
docker restart node001 node002
node001
node002
在node001上添加用戶(hù)并授權(quán):
CREATE USER 'tongbu'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'tongbu'@'%';
在node002上添加用戶(hù)并授權(quán):
CREATE USER 'tongbu'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'tongbu'@'%';
在node001要查看master信息:
mysql> show master status\G;
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 656
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.01 sec)
ERROR:
No query specified
mysql>
在node002上設(shè)置從節(jié)點(diǎn),進(jìn)行以下操作,注意master_log_file='mysql-bin.000001',master_log_pos=656;要與上一步查看到的node001信息一致:最后執(zhí)行 start slave;
change master to
master_host='192.168.101.6',master_port=3333,master_user='tongbu',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=656;
start slave;
查看node002的slave狀態(tài)(確保標(biāo)紅處的兩個(gè)Yes):
show slave status \G
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.101.6
Master_User: tongbu
Master_Port: 3333
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 656
Relay_Log_File: 914fdc4fdb40-relay-bin.000002
Relay_Log_Pos: 326
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
在node002要查看master信息:
mysql> show master status\G;
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 656
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
ERROR:
No query specified
mysql>
在node001上設(shè)置從節(jié)點(diǎn),進(jìn)行以下操作,注意master_log_file='mysql-bin.000001',master_log_pos=656;要與上一步查看到的node001信息一致:最后執(zhí)行 start slave;
change master to
master_host='192.168.101.6',master_port=4444,master_user='tongbu',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=656;
start slave;
查看node001的slave狀態(tài)(確保標(biāo)紅處的兩個(gè)Yes):
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.101.6
Master_User: tongbu
Master_Port: 4444
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 656
Relay_Log_File: f061023a72b4-relay-bin.000002
Relay_Log_Pos: 326
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
測(cè)試node001增加一個(gè)test數(shù)據(jù)庫(kù):
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)
mysql> create database test;
Query OK, 1 row affected (0.03 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
mysql>
查看node002上的數(shù)據(jù)庫(kù),已經(jīng)與node001同步:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
mysql>
在node002上刪除test數(shù)據(jù)庫(kù):
mysql> drop database test;
Query OK, 0 rows affected (0.02 sec)
mysql>
在node001上查看數(shù)據(jù)庫(kù),已經(jīng)與node002同步:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql>
在node002上增加一個(gè)數(shù)據(jù)庫(kù)test002:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> create database test002;
Query OK, 1 row affected (0.04 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test002 |
+--------------------+
5 rows in set (0.01 sec)
mysql>
查看node001上的數(shù)據(jù)庫(kù),已經(jīng)與node002同步:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test002 |
+--------------------+
5 rows in set (0.00 sec)
mysql>
原文來(lái)源:https://mp.weixin.qq.com/s/DgplLEGFfcoAWharuZA86Q
來(lái)源:本文內(nèi)容搜集或轉(zhuǎn)自各大網(wǎng)絡(luò)平臺(tái),并已注明來(lái)源、出處,如果轉(zhuǎn)載侵犯您的版權(quán)或非授權(quán)發(fā)布,請(qǐng)聯(lián)系小編,我們會(huì)及時(shí)審核處理。
聲明:江蘇教育黃頁(yè)對(duì)文中觀點(diǎn)保持中立,對(duì)所包含內(nèi)容的準(zhǔn)確性、可靠性或者完整性不提供任何明示或暗示的保證,不對(duì)文章觀點(diǎn)負(fù)責(zé),僅作分享之用,文章版權(quán)及插圖屬于原作者。
Copyright?2013-2024 JSedu114 All Rights Reserved. 江蘇教育信息綜合發(fā)布查詢(xún)平臺(tái)保留所有權(quán)利
蘇公網(wǎng)安備32010402000125
蘇ICP備14051488號(hào)-3技術(shù)支持:南京博盛藍(lán)睿網(wǎng)絡(luò)科技有限公司
南京思必達(dá)教育科技有限公司版權(quán)所有 百度統(tǒng)計(jì)