1. 程式人生 > 資料庫 >基於Docker如何實現MySQL主從複製詳解

基於Docker如何實現MySQL主從複製詳解

前言

MySQL的主從複製是實現應用的高效能,高可用的基礎。對於資料庫讀操作較密集的應用,通過使資料庫請求負載均衡分配到不同MySQL伺服器,可有效減輕資料庫壓力。當遇到MySQL單點故障中,也能在短時間內實現故障切換。本文就MySQL的內建的複製功能進行闡述。

版本

  • MySQl: 5.7.17
  • CentOS: 7.4.1708
  • Docker: 1.13.1

概述

MySQL複製資料流程:

  1. 主庫在資料更新提交事務之前,將事件非同步記錄到binlog二進位制日誌檔案中,日誌記錄完成後儲存引擎提交本次事務
  2. 從庫啟動一個I/O執行緒與主庫建立連線,用來請求主庫中要更新的binlog。這時主庫建立的binlog dump執行緒,這是二進位制轉儲執行緒,如果有新更新的事件,就通知I/O執行緒;當該執行緒轉儲二進位制日誌完成,沒有新的日誌時,該執行緒進入sleep狀態。
  3. 從庫的I/O執行緒接收到新的事件日誌後,儲存到自己的relay log(中繼日誌)中
  4. 從庫的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的複製雖然使用簡單方便,但也伴隨著一些問題需要我們在使用中進行解決,比如:不能從伺服器異常停止中恢復,資料同步的延遲等等,還好現在遇到的大部分問題在行業中已得到相應的解決。對這方面感興趣的可以去了解下現在解決這些問題的中介軟體實現方案。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對我們的支援。