Docker-Compose實現Mysql主從
1. 簡介
通過使用docker-compose 搭建一個主從數據庫,本示例為了解耦 將兩個server拆分到了兩個compose文件中,當然也可以放到一個compose文件中
演示mysql版本:5.7.16
2. 部署流程
master節點:
- 安裝mysql-server
- 修改配置
- 創建用于同步的賬號并授權
- 檢查相關配置
slave節點:
- 安裝mysql-server
- 修改配置
- 選擇主節點
- 檢查相關配置并驗證同步功能
3. master節點
3.1 安裝mysql
-
創建mysql文件夾并進入文件夾(文件夾名稱mysql)
-
創建docker-compose文件內容如下
# docker-compose.yml version: '3' services: mysql: restart: "no" image: mysql:5.7.16 container_name: mysql-master volumes: - ./datadir:/var/lib/mysql - ./conf/mysql:/etc/mysql environment: - "MYSQL_ROOT_PASSWORD=123456" - "TZ=Asia/Shanghai" ports: - 3306:3306 networks: - mysql-net networks: mysql-net: driver: bridge注意:因為要把配置文件掛在到服務中去,所以要先把容器中的配置文件copy到宿主機上
-
先啟動一個用于copy文件的容器
$ docker run --name mysql-temp -e MYSQL_ROOT_PASSWORD=root --rm -d mysql:5.7.16 -
將
mysql-temp容器中的配置文件copy出來,現在conf文件夾中就是mysql自帶的所有配置文件$ docker cp mysql-temp:/etc/mysql conf
-
因為當前conf目錄中的
my.cnf還是個link,所以直接使用當前目錄中的備份文件作為主要的配置文件$ mv my.cnf.fallback my.cnf
-
-
修改配置文件
my.cnf在文件的最下方加入配置信息
[mysqld] log-bin=mysql-bin # 開啟 binlog server-id=1 # 當前server在cluster中的id,必須保證在cluster中唯一 #只保留7天的二進制日志,以防磁盤被日志占滿(可選) expire-logs-days = 7 #不備份的數據庫 (可選) binlog-ignore-db=information_schema binlog-ignore-db=performation_schema binlog-ignore-db=sys -
啟動mysql服務,通過輸出內容得知真實的網絡名稱為
mysql_mysql-net,也就是當前所在文件夾的名稱拼接了文件中指定的網絡名稱
-
服務啟動完畢后,創建用于同步的用戶并授權
創建的用戶名稱為
slave密碼為123456CREATE USER 'slave' @'%' IDENTIFIED BY '123456'; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave' @'%'; #刷新權限 FLUSH PRIVILEGES; -
查看master狀態信息
SHOW MASTER STATUS; #查看Mater數據有哪些slave select * from information_schema.processlist as p where p.command = 'Binlog Dump';
4. slave節點
安裝步驟同master相同,只把需要修改的展示一下,當前的目錄結構如下

docker-compose.yaml 主要修改了網絡相關的信息和container_name(網絡名稱上面有解釋)
version: '3'
services:
mysql:
restart: "no"
image: mysql:5.7.16
container_name: mysql-slave
volumes:
- ./datadir:/var/lib/mysql
- ./conf:/etc/mysql
environment:
- "MYSQL_ROOT_PASSWORD=123456"
- "TZ=Asia/Shanghai"
ports:
- 3307:3306
networks:
- mysql_mysql-net
networks:
mysql_mysql-net:
external: true # 來自外部
my.cnf添加的內容如下:
[mysqld]
server-id=2
relay_log=relay-log
#開啟只讀 意味著當前的數據庫用作讀,當然這也只會影響到非root的用戶,如果使用root用戶操作本庫是不會有影響的
read_only=ON
設置完成后啟動salve server,連接slave并關聯master節點
MASTER_HOST:直接使用container_nameMASTER_LOG_FILE/MASTER_LOG_POS:直接使用安裝master步驟中的最后一步的值,其實就是指定同步的bin-log文件名稱和Offset
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='slave',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
管理完成后 啟動salve
START SLAVE;
最后查看slave status
SHOW SLAVE STATUS;

5. 驗證
在master上創建test數據庫并創建user表,刷新查看salve庫,出現了對應的庫表

經驗證數據同步也沒有問題。
6. 可能遇到的問題
SHOW SLAVE STATUS時發現 slave_io_running=No salve_sql_running=No,可能的原因有很多,可以查看如下的字段中輸出的內容

可能的原因:
- 主從網絡不通
- 兩臺節點的
server-id重復,直接修改對應的id即可 - 數據庫的uuid相同(可能是因為數據庫文件是直接copy過來的導致的),在對應的庫下生成不同于master的uuid到
auto.cnf中即可 - sql執行失敗,可能是slave剛添加進來,也沒有master庫的數據庫instance,導致操作對應的庫時slave這邊根本沒有對應的instance或者table又或是記錄,引發的報錯。這個只能具體問題具體解決了
- master和slave的
MASTER_LOG_FILE/MASTER_LOG_POS值設置的有問題,在slave節點上STOP SLAVE;然后重新連接下master即可
7. 同步部分數據庫實例或表
在master節點上添加配置【可選】(如果只希望從庫讀取到部分實例)
在my.cnf文件中加入如下配置
#需要同步的數據庫名 有多個庫添加多行即可
binlog-do-db=test
binlog-do-db=test1
#排除的數據庫
binlog-ignore-db=sys
salve端:在my.cnf文件中加入如下配置,這樣的話salve只會讀取配置的db或table,master對其他db的操作也不會影響slave
#如果salve庫名稱與master庫名相同,使用本配置
replicate-do-db=test
#如果master庫名[test]與salve庫名[test001]不同,使用以下配置[需要做映射]
#replicate-rewrite-db = test -> test001
#如果不是要全部同步[默認全部同步],則指定需要同步的表
#replicate-wild-do-table=test.user
#replicate-wild-do-table=test.role

浙公網安備 33010602011771號