
前言
MySQL的主從復制是實作應用的高性能,高可用的基礎,對于資料庫讀操作較密集的應用,通過使資料庫請求負載均衡分配到不同MySQL服務器,可有效減輕資料庫壓力,當遇到MySQL單點故障中,也能在短時間內實作故障切換,本文就MySQL的內建的復制功能進行闡述,
版本
- MySQl:
5.7.17 - CentOS:
7.4.1708 - Docker:
1.13.1
概述
MySQL復制資料流程:
- 主庫在資料更新提交事務之前,將事件異步記錄到binlog二進制日志檔案中,日志記錄完成后存盤引擎提交本次事務
- 從庫啟動一個I/O執行緒與主庫建立連接,用來請求主庫中要更新的binlog,這時主庫創建的binlog dump執行緒,這是二進制轉儲執行緒,如果有新更新的事件,就通知I/O執行緒;當該執行緒轉儲二進制日志完成,沒有新的日志時,該執行緒進入sleep狀態,
- 從庫的I/O執行緒接收到新的事件日志后,保存到自己的relay log(中繼日志)中
- 從庫的SQL執行緒讀取中繼日志中的事件,并執行更新保存,

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

- data 目錄用來保存資料檔案的目錄
- Dockerfile 保存Dockerfile內容
- init.sql 初始化資料庫的SQL
- my.cnf 資料庫組態檔,配置方式上面已提到
- start.sh Dockerfile構建MySQL時的腳本
Dockerfile 內容
# 利用 mysql 鏡像創建新的鏡像
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都是基于同一個鏡像構建,使用的存盤引擎和其他的組件最好是同一中,不然在復制程序中可能會出現例外,
init.sql 初始化資料
-- 創建 data_copy 資料庫
DROP DATABASE IF EXISTS `data_copy`;
CREATE DATABASE `data_copy` /*!40100 DEFAULT CHARACTER SET utf8mb4 collate utf8mb4_general_ci */;
-- 創建 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;
創建data_copy資料庫和person表,
start.sh 腳本
#!/bin/sh
echo '啟動mysql'
service mysql start
sleep 5
echo '初始化資料庫'
mysql -uroot -pytao < /mysql/init.sql
echo '初始化完成!'
tail -f /dev/null
構建master和slave鏡像并運行容器
構建master鏡像
docker build -t master/mysql .
構建slave鏡像
docker build -t slave/mysql .
構建成功會回傳 Successfuly,或通過docker images命令查看鏡像

使用剛構建的鏡像來運行容器
# 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目錄為保存資料的目錄,
連接到資料庫后驗證資料庫是否初始化成功

查看 log-bin 是否開啟

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

上面標記的輸出資訊Slave_IO_Running: Yes和Slave_SQL_Running: Yes可以看到I/O執行緒和SQL執行緒已啟動運行中,
測驗同步資料
如果在主庫中添加,更新或洗掉一個資料,那么從庫中應該也有與主庫對應的資料變化,
向主庫添加一條資料
INSERT INTO `data_copy`.`person` (`id`, `name`) VALUES ('1', 'ytao');
查詢從庫資料,資料已被同步過來,

總結
上述是最簡單最基本的配置,但是理解上面的配置程序,就可以根據自身情況定制不同方案,實作一主多從,主主復制(主動-主動或主動-被動模式)等等來滿足自身需求,
MySQL的復制雖然使用簡單方便,但也伴隨著一些問題需要我們在使用中進行解決,比如:不能從服務器例外停止中恢復,資料同步的延遲等等,還好現在遇到的大部分問題在行業中已得到相應的解決,對這方面感興趣的可以去了解下現在解決這些問題的中間件實作方案,
個人博客: https://ytao.top
我的公眾號 ytao

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/113119.html
標籤:MySQL
上一篇:MYSQL練習隨筆
下一篇:mysql慢日志分析組件安裝
