基于Docker如何實(shí)現(xiàn)MySQL主從復(fù)制詳解
前言
MySQL的主從復(fù)制是實(shí)現(xiàn)應(yīng)用的高性能,高可用的基礎(chǔ)。對于數(shù)據(jù)庫讀操作較密集的應(yīng)用,通過使數(shù)據(jù)庫請求負(fù)載均衡分配到不同MySQL服務(wù)器,可有效減輕數(shù)據(jù)庫壓力。當(dāng)遇到MySQL單點(diǎn)故障中,也能在短時(shí)間內(nèi)實(shí)現(xiàn)故障切換。本文就MySQL的內(nèi)建的復(fù)制功能進(jìn)行闡述。
版本
- MySQl: 5.7.17
- CentOS: 7.4.1708
- Docker: 1.13.1
概述
MySQL復(fù)制數(shù)據(jù)流程:
- 主庫在數(shù)據(jù)更新提交事務(wù)之前,將事件異步記錄到binlog二進(jìn)制日志文件中,日志記錄完成后存儲(chǔ)引擎提交本次事務(wù)
- 從庫啟動(dòng)一個(gè)I/O線程與主庫建立連接,用來請求主庫中要更新的binlog。這時(shí)主庫創(chuàng)建的binlog dump線程,這是二進(jìn)制轉(zhuǎn)儲(chǔ)線程,如果有新更新的事件,就通知I/O線程;當(dāng)該線程轉(zhuǎn)儲(chǔ)二進(jìn)制日志完成,沒有新的日志時(shí),該線程進(jìn)入sleep狀態(tài)。
- 從庫的I/O線程接收到新的事件日志后,保存到自己的relay log(中繼日志)中
- 從庫的SQL線程讀取中繼日志中的事件,并執(zhí)行更新保存。

配置主從庫
主庫my.cnf配置
在主庫的my.cnf中打開二進(jìn)制日志,并設(shè)置服務(wù)Id。
log-bin = mysql-bin server-id = 1
注意server-id必須是一個(gè)唯一的數(shù)字,必須主從不一致, 且主從庫必須設(shè)置項(xiàng)。
從庫my.cnf配置
log-bin = mysql-bin server-id = 2 log-slave-updates = 1 read-only = 1
從庫也開啟log-bin,log-slave-updates設(shè)置為從庫重放中繼日志時(shí),記錄到自己的二進(jìn)制日志中,可以讓從庫作為其他服務(wù)器的主庫,將二進(jìn)制日志轉(zhuǎn)發(fā)給其他從庫,在做一主多從方案時(shí)可考慮該種方案。
Dockerfile構(gòu)建MySQL鏡像
構(gòu)建所需文件
這里master和slave文件各自保存不共用,先創(chuàng)建文件夾 /usr/local/mysql 然后在目錄創(chuàng)建master和slave兩個(gè)目錄,再各自創(chuàng)建data文件夾

- data 目錄用來保存數(shù)據(jù)文件的目錄
- Dockerfile 保存Dockerfile內(nèi)容
- init.sql 初始化數(shù)據(jù)庫的SQL
- my.cnf 數(shù)據(jù)庫配置文件,配置方式上面已提到
- start.sh Dockerfile構(gòu)建MySQL時(shí)的腳本
Dockerfile 內(nèi)容
# 利用 mysql 鏡像創(chuàng)建新的鏡像 FROM mysql:5.7.17 ENV MYSQL_ROOT_PASSWORD ytao COPY start.sh /mysql/start.sh COPY my.cnf /etc/mysql/my.cnf COPY init.sql /mysql/init.sql EXPOSE 3306 CMD ["sh", "/mysql/start.sh"]
這里的master和slave都是基于同一個(gè)鏡像構(gòu)建,使用的存儲(chǔ)引擎和其他的組件最好是同一中,不然在復(fù)制過程中可能會(huì)出現(xiàn)異常。
init.sql 初始化數(shù)據(jù)
-- 創(chuàng)建 data_copy 數(shù)據(jù)庫 DROP DATABASE IF EXISTS `data_copy`; CREATE DATABASE `data_copy` /*!40100 DEFAULT CHARACTER SET utf8mb4 collate utf8mb4_general_ci */; -- 創(chuàng)建 person 表 USE `data_copy`; DROP TABLE IF EXISTS `person`; CREATE TABLE `person` ( `id` int(32) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
創(chuàng)建data_copy數(shù)據(jù)庫和person表。
start.sh 腳本
#!/bin/sh echo '啟動(dòng)mysql' service mysql start sleep 5 echo '初始化數(shù)據(jù)庫' mysql -uroot -pytao < /mysql/init.sql echo '初始化完成!' tail -f /dev/null
構(gòu)建master和slave鏡像并運(yùn)行容器
構(gòu)建master鏡像
docker build -t master/mysql .
構(gòu)建slave鏡像
docker build -t slave/mysql .
構(gòu)建成功會(huì)返回 Successfuly,或通過docker images命令查看鏡像

使用剛構(gòu)建的鏡像來運(yùn)行容器
# master 容器 docker run --name master -p 3306:3306 -v /usr/local/mysql/master/data/:/var/lib/mysql -d master/mysql # slave 容器 docker run --name slave -p 3307:3306 -v /usr/local/mysql/slave/data/:/var/lib/mysql -d slave/mysql
指定master端口為3306,slave端口為3307,掛載data目錄為保存數(shù)據(jù)的目錄。
連接到數(shù)據(jù)庫后驗(yàn)證數(shù)據(jù)庫是否初始化成功

查看 log-bin 是否開啟

創(chuàng)建復(fù)制賬號
前面有提到從庫I/O線程要與主庫建立連接,所以需要用到賬號進(jìn)行驗(yàn)證。賬號除了要有連接權(quán)限(REPLICATION CLIENT),同時(shí)還要有復(fù)制權(quán)限(REPLICATION SLAVE)。
GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO muser@'%' IDENTIFIED BY 'ytao';
這里設(shè)置的訪問地址是開放的,實(shí)際使用過程中安全起見一定要指定訪問地址。
從庫啟動(dòng)復(fù)制
從庫連接到主庫,獲取到二進(jìn)制日志后重放。這里首先要配置上面創(chuàng)建的賬號進(jìn)行連接,使用命令進(jìn)行相應(yīng)的設(shè)置。
CHANGE MASTER TO MASTER_HOST = '47.107.xx.xxx', MASTER_PORT = 3306, MASTER_USER = 'muser', MASTER_PASSWORD = 'ytao', MASTER_LOG_FILE = 'mysql-bin.000006';
到這里復(fù)制還沒有啟動(dòng),需要再從庫中啟動(dòng)
START SLAVE;
使用SHOW SLAVE STATUS\G;命令查看啟動(dòng)后的情況

上面標(biāo)記的輸出信息Slave_IO_Running: Yes和Slave_SQL_Running: Yes可以看到I/O線程和SQL線程已啟動(dòng)運(yùn)行中。
測試同步數(shù)據(jù)
如果在主庫中添加,更新或刪除一個(gè)數(shù)據(jù),那么從庫中應(yīng)該也有與主庫對應(yīng)的數(shù)據(jù)變化。
向主庫添加一條數(shù)據(jù)
INSERT INTO `data_copy`.`person` (`id`, `name`) VALUES ('1', 'ytao');
查詢從庫數(shù)據(jù),數(shù)據(jù)已被同步過來。

總結(jié)
上述是最簡單最基本的配置,但是理解上面的配置過程,就可以根據(jù)自身情況定制不同方案,實(shí)現(xiàn)一主多從,主主復(fù)制(主動(dòng)-主動(dòng)或主動(dòng)-被動(dòng)模式)等等來滿足自身需求。
MySQL的復(fù)制雖然使用簡單方便,但也伴隨著一些問題需要我們在使用中進(jìn)行解決,比如:不能從服務(wù)器異常停止中恢復(fù),數(shù)據(jù)同步的延遲等等,還好現(xiàn)在遇到的大部分問題在行業(yè)中已得到相應(yīng)的解決。對這方面感興趣的可以去了解下現(xiàn)在解決這些問題的中間件實(shí)現(xiàn)方案。
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。
相關(guān)文章
簡述Docker安裝Tomcat鏡像并部署web項(xiàng)目
這篇文章主要介紹了簡述Docker安裝Tomcat鏡像并部署web項(xiàng)目,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
Docker安全開放遠(yuǎn)程訪問連接權(quán)限方式
文章介紹了如何配置Docker以實(shí)現(xiàn)遠(yuǎn)程訪問、開啟認(rèn)證和通信加密,包括生成證書和私鑰、配置Docker守護(hù)進(jìn)程以及在IDEA和Maven中連接Docker服務(wù)的方法2024-11-11
docker-compose如何實(shí)現(xiàn)滾動(dòng)更新
這篇文章主要介紹了docker-compose如何實(shí)現(xiàn)滾動(dòng)更新方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Spring Boot應(yīng)用通過Docker發(fā)布部署的流程分析
將Spring Boot項(xiàng)目部署到docker中有兩種方法,手動(dòng)部署和插件部署,本文通過實(shí)例代碼介紹了idea創(chuàng)建spring boot項(xiàng)目的詳細(xì)過程,感興趣的朋友一起看看吧2021-09-09
解決nacos啟動(dòng)時(shí)防火墻開啟8848的坑
最近操作Nacos時(shí)遭遇8848端口無法訪問的問題,嘗試通過安全組和firewall配置仍無法解決,最終發(fā)現(xiàn),firewall對Docker使用專門的作用域,需要在相應(yīng)作用域下開放端口,務(wù)必檢查firewall中針對Docker的設(shè)置,確保8848端口在正確的作用域內(nèi)被允許通行2022-10-10

