成都優(yōu)化網(wǎng)站哪家公司好seo優(yōu)化網(wǎng)站的手段
笑小楓的專屬目錄
- 一、無聊的理論知識
- 1. 主從復(fù)制原理
- 2. 主從復(fù)制的工作過程
- 3. MySQL四種同步方式
- 二、docker下安裝、啟動mysql
- 1. 安裝主庫
- 2. 安裝從庫
- 三、配置Master(主)
- 四、配置Slave(從)
- 五、鏈接Master(主)和Slave(從)
- 六、主從復(fù)制排錯
- 1. 錯誤:error connecting to master 'xxxx' - retry-time: 30 retries: xx
- 2. 錯誤:ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository
- 3. 操作從庫配置后,主庫發(fā)生變更
- 七、測試主從復(fù)制測試
- 八、總結(jié)
一、無聊的理論知識
MySQL的主從復(fù)制和MySQL的讀寫分離兩者有著緊密聯(lián)系,首先要部署主從復(fù)制,只有主從復(fù)制完成了,才能在此基礎(chǔ)上進行數(shù)據(jù)的讀寫分離
1. 主從復(fù)制原理
mysql支持的復(fù)制類型:
①STATEMENT:基于語句的復(fù)制,在主服務(wù)器上執(zhí)行sql語句,在從服務(wù)器上執(zhí)行同樣的語句,MySQL默認采用基于語句的復(fù)制,執(zhí)行效率高
②ROW:基于行的復(fù)制,把改變的內(nèi)容復(fù)制過去,而不是把命令在從服務(wù)器上執(zhí)行一邊
③MIXED:混合類型的復(fù)制,默認采用基于語句的復(fù)制,一旦發(fā)現(xiàn)基于語句無法精確復(fù)制時,就會采用基于行的復(fù)制
2. 主從復(fù)制的工作過程
主從復(fù)制核心部分就是兩個日志、三個線程(高版本的mysql以及異步復(fù)制、半同步復(fù)制、全同步復(fù)制
核心重點:兩個日志文件:二進制日志、中繼日志、三個線程:master的dump thread、slave的IO、SQL
主要原理:master將數(shù)據(jù)保存在二進制日志中,IO向dump發(fā)出同步請求,dump把數(shù)據(jù)發(fā)送給IO線程。IO會寫入到本地的中繼日志,SQL線程會讀取本地的日志數(shù)據(jù),同步到自己的數(shù)據(jù)庫中,完成同步
①Master節(jié)點將數(shù)據(jù)的改變記錄成二進制日志(bin log),當(dāng)Master上的數(shù)據(jù)發(fā)生改變時,則將其改變寫入二進制日志中
②Slave節(jié)點會在一定時間間隔內(nèi)對Master的二進制日志進行探測其是否發(fā)生改變,如果發(fā)生改變,則開始一個I/O線程請求Master的二進制時間
③同時Master節(jié)點為每個I/O線程啟動一個dump線程,用于向其發(fā)生二進制事件,并保存至Slave節(jié)點本地的中繼日志(Relay log)中,Slave節(jié)點將啟動SQL線程從中繼日志中讀取二進制日志,在本地重放,即解析成sql語句逐一執(zhí)行,使得其數(shù)據(jù)和Master節(jié)點的保持一致,最后I/O線程和SQL線程將進入睡眠狀態(tài),等待下一次被喚醒
**注:**中繼日志通常會位于OS緩存中,所以中繼日志的開銷很小
復(fù)制過程有一個很重要的限制,即復(fù)制在Slave上是串行化的,也就是說Master上的并行更新操作不能在Slave上并行操作
主MySQL服務(wù)器做的增刪改操作,都會寫入自己的二進制日志(Binary log)
然后從MySQL從服務(wù)器打開自己的I/O線程連接主服務(wù)器,進行讀取主服務(wù)器的二進制日志
I/O去監(jiān)聽二進制日志,一旦由新的數(shù)據(jù),會發(fā)起請求連接
這時候會觸發(fā)dump線程,dump thread響應(yīng)請求,傳送數(shù)據(jù)給I/O(dump線程要么處于等待,要么處于睡眠狀態(tài))
I/O接收到數(shù)據(jù)之后存放在中繼日志
SQL thread線程會讀取中繼日志里的數(shù)據(jù),存放到自己的服務(wù)器中dump通過TP也就是網(wǎng)絡(luò)的方式發(fā)送給IO
3. MySQL四種同步方式
異步復(fù)制(Async Replication)
主庫將更新寫入Binlog日志文件,不需要等待數(shù)據(jù)更新是否已經(jīng)復(fù)制到從庫中,就可以繼續(xù)處理更多的請求,Master將事件寫入binlog,但并不知道Slave是否或何時已經(jīng)接收且已處理,在異步復(fù)制的機制的情況下,如果Master宕機,事務(wù)在Master上已經(jīng)提交,但可能這些事務(wù)沒有傳到任何的Slave上,假設(shè)有Master–>Salve故障轉(zhuǎn)移的機制,此時Slave也可能會丟失事務(wù),Mysql復(fù)制默認是異步復(fù)制,異步復(fù)制提供了最佳性能
同步復(fù)制(Sync Replication)
主庫將更新寫入Binlog日志文件后,需要等待數(shù)據(jù)更新已經(jīng)復(fù)制到從庫中,并且已經(jīng)在從庫執(zhí)行成功,然后才能返回繼續(xù)處理其它的請求,同步復(fù)制提供了最佳安全性,保證數(shù)據(jù)安全,數(shù)據(jù)不會丟失,但對性能有一定的影響
半同步復(fù)制(Semi-Sync Replication)
主庫提交更新寫入二進制日志文件后,等待數(shù)據(jù)更新寫入了從服務(wù)器中繼日志中,然后才能再繼續(xù)處理其它請求,該功能確保至少有1個從庫接收完主庫傳遞過來的binlog內(nèi)容已經(jīng)寫入到自己的relay log里面了,才會通知主庫上面的等待線程,該操作完畢
半同步復(fù)制是最佳安全性于最佳性能 之間的一個折中
MySQL5.5版本之中引入了半同步復(fù)制功能,主從服務(wù)器必須安裝半同步復(fù)制插件,才能開啟該復(fù)制功能,如果等待超時,超過rpl_semi_sync_master_timeout參數(shù)設(shè)置時間(默認值為10000,表示10秒),則關(guān)閉半同步復(fù)制。并自動轉(zhuǎn)換為異步復(fù)制模式,當(dāng)master dump線程發(fā)送完一個事務(wù)的所有事件之后,如果在rpl_semi_sync_master_timeout內(nèi),收到了從庫的響應(yīng),則主從又重新恢復(fù)為增強半同步復(fù)制
ACK (Acknowledge character)即是確認字符。
增強半同步復(fù)制(lossless Semi-Sync Replication、無損復(fù)制)
增強半同步時在MySQL 5.7引入,其實半同步可以看成一個過渡功能,因為默認的配置就是增強半同步,大家一般說的半同步復(fù)制其實就是增強的半同步復(fù)制,也就是無損復(fù)制
增強半同步和半同步不同的是,等待ACK時間不同
rpl_semi_sync_master_wait_point =AFTER_SYNC(默認)
半同步的問題是因為等待ACK的點是Commit之后,此時Master已經(jīng)完成數(shù)據(jù)變更,用戶已經(jīng)可以看到最新數(shù)據(jù),當(dāng)Binlog還未同步到Slave時,發(fā)生主從切換,那么此時從庫是沒有這個最新數(shù)據(jù)的,用戶看到的還是老數(shù)據(jù),增強半同步將等待ACK的點放在提交Commit之前,此時數(shù)據(jù)還未被提交,外界看不到數(shù)據(jù)變更,此時如果發(fā)生主從切換,新庫依然還是老數(shù)據(jù),不存在數(shù)據(jù)不一致的問題
二、docker下安裝、啟動mysql
docker下安裝mysql 8.0.15
docker pull mysql:8.0.15
1. 安裝主庫
啟動mysql-master,當(dāng)作主庫
docker run -p 3320:3306 --name mysql_master -e MYSQL_ROOT_PASSWORD=123456 -d 7bb2586065cd
此時啟動已完成,在docker啟動鏡像時密碼加密使用的是caching_sha2_password,
在服務(wù)器端啟動默認使用mysql_native_password 加密的,
如需要使用外部工具連接,需要進入docker容器重置root密碼。
進入docker容器修改Mysql遠程連接的密碼
docker exec -it mysql_master /bin/sh# mysql -u root -p輸入登錄密碼(設(shè)置的MYSQL_ROOT_PASSWORD):123456mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'test001';
退出數(shù)據(jù)庫設(shè)置和docker容器,使用exit命令
2. 安裝從庫
啟動mysql-slave,當(dāng)作從庫
docker run -p 3321:3306 --name mysql_slave -e MYSQL_ROOT_PASSWORD=123456 -d 7bb2586065cd
進入docker容器修改Mysql遠程連接的密碼
docker exec -it mysql_slave /bin/sh# mysql -u root -p輸入登錄密碼(設(shè)置的MYSQL_ROOT_PASSWORD):123456mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'test001';
安裝完主庫和從庫后如下所示:
三、配置Master(主)
docker exec -it mysql_master /bin/sh
cd /etc/mysql
切換到/etc/mysql目錄下,然后vi my.cnf
對my.cnf進行編輯。
此時會報出bash: /bin/sh: 3: vi: not found
,需要我們在docker容器內(nèi)部自行安裝vim。
使用apt-get install vim
命令安裝vim
如果出現(xiàn)如下問題:
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package vim
執(zhí)行apt-get update
,然后再次執(zhí)行apt-get install vim
即可成功安裝vim。
如果docker內(nèi)部安裝不了Vim,可以將文件拷貝出來,修改完之后在拷貝進去,或者啟動時使用docker -v的方式掛載
#將容器中的文件拷貝出來 sudo docker cp 容器ID:/etc/mysql/my.cnf /data/mysql/master #將容器中的文件拷貝回去 sudo docker cp /data/mysql/master/my.cnf 容器ID:/etc/mysql/
然后我們就可以使用vim編輯my.cnf,在my.cnf中添加
[mysqld]
## 同一局域網(wǎng)內(nèi),注意要唯一
server-id=99
## 開啟二進制日志功能,可以隨便取(關(guān)鍵)
log-bin=mysql-bin
需要重啟mysql服務(wù),
docker restart 容器ID
下一步在Master數(shù)據(jù)庫創(chuàng)建數(shù)據(jù)同步用戶
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
授予用戶 slave REPLICATION SLAVE權(quán)限和REPLICATION CLIENT權(quán)限,用于在主從庫之間同步數(shù)據(jù)。
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
四、配置Slave(從)
和配置Master(主)一樣,在Slave配置文件my.cnf中添加如下配置:
[mysqld]
## 設(shè)置server_id,注意要唯一
server-id=101
## 開啟二進制日志功能,以備Slave作為其它Slave的Master時使用
log-bin=mysql-slave-bin
## relay_log配置中繼日志
relay_log=edu-mysql-relay-bin
配置完成后也需要重啟mysql服務(wù)和docker容器,操作和配置Master(主)一致。
五、鏈接Master(主)和Slave(從)
在Master進入mysql,執(zhí)行show master status;
File和Position字段的值后面將會用到,在后面的操作完成之前,需要保證Master庫不能做任何操作,否則將會引起狀態(tài)變化,File和Position字段的值變化。
在Slave 中進入 mysql,執(zhí)行
change master to master_host='172.17.0.8', master_user='slave', master_password='test001', master_port=3306, master_log_file='mysql-bin.000002', master_log_pos=994, master_connect_retry=30;
- 命令說明
master_host :Master的地址,指的是容器的獨立ip,可以通過docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名稱|容器id查詢?nèi)萜鞯膇p。如果不是docker直接放服務(wù)器的IP地址就行,保證兩個服務(wù)器互通即可master_port:Master的端口號,指的是容器的端口號master_user:用于數(shù)據(jù)同步的用戶master_password:用于同步的用戶的密碼master_log_file:指定 Slave 從哪個日志文件開始復(fù)制數(shù)據(jù),即上文中提到的 File 字段的值master_log_pos:從哪個 Position 開始讀,即上文中提到的 Position 字段的值master_connect_retry:如果連接失敗,重試的時間間隔,單位是秒,默認是60秒
在Slave 中的mysql終端執(zhí)行show slave status;
用于查看主從同步狀態(tài)。
- Slave_IO_Running:負責(zé)從庫去主庫讀取二進制日志,并寫入到從庫的中繼日志
- Slave_SQL_Running:負責(zé)將中繼日志轉(zhuǎn)換成SQL語句后執(zhí)行
正常情況下,SlaveIORunning 和 SlaveSQLRunning 都是No,因為我們還沒有開啟主從復(fù)制過程。
使用start slave;
開啟主從復(fù)制過程,然后再次查詢主從同步狀態(tài)show slave status;
。
SlaveIORunning 和 SlaveSQLRunning 都是Yes,說明主從復(fù)制已經(jīng)開啟。此時可以測試數(shù)據(jù)同步是否成功。
六、主從復(fù)制排錯
1. 錯誤:error connecting to master ‘xxxx’ - retry-time: 30 retries: xx
使用start slave開啟主從復(fù)制過程后,如果SlaveIORunning一直是Connecting,則說明主從復(fù)制一直處于連接狀態(tài),這種情況一般是下面幾種原因造成的,我們可以根據(jù) Last_IO_Error提示予以排除。
1、網(wǎng)絡(luò)不通
檢查ip,端口,這里docker雖然映射出去的mysql端口是3320,但通過內(nèi)網(wǎng)訪問仍然是3306
2、密碼不對
檢查是否創(chuàng)建用于同步的用戶和用戶密碼是否正確
3、pos不對
檢查Master的 Position
2. 錯誤:ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository
檢查my.cnf,是否指定relay_log,指定的relay_log是否被其他server占用。
解決方法:修改my.cnf指定relay_log,然后重啟服務(wù)。
先執(zhí)行reset slave
命令,在執(zhí)行以下命令:
change master to master_host='172.17.0.8', master_user='slave', master_password='test001', master_port=3306, master_log_file='mysql-bin.000002', master_log_pos=994, master_connect_retry=30;
最后啟動start slave;
3. 操作從庫配置后,主庫發(fā)生變更
在mastershow master status;
查詢主庫最新的狀態(tài)
然后執(zhí)行reset slave
命令,再執(zhí)行更新后的鏈接命令:
change master to master_host='172.17.0.8', master_user='slave', master_password='test001', master_port=3306, master_log_file='mysql-bin.000002', master_log_pos=994, master_connect_retry=30;
最后啟動start slave;
七、測試主從復(fù)制測試
在主庫(master)創(chuàng)建test數(shù)據(jù)庫,并添加test表,然后可以看到從庫中也出現(xiàn)了對應(yīng)的數(shù)據(jù)庫和表
八、總結(jié)
本文主要講解了Mysql主從復(fù)制的操作,如果有多個從庫,重復(fù)執(zhí)行從庫的操作即可。
切記:對數(shù)據(jù)的增刪改操作一定要在主庫上操作,不要在從庫上操作。
本文到此就結(jié)束了,有問題就找笑小楓。
點個關(guān)注和收藏吧,不然就👇👇👇👇👇👇👇👇👇