通過使用docker-compose
搭建一個主從資料庫,本範例為了解耦 將兩個server拆分到了兩個compose檔案中,當然也可以放到一個compose檔案中
演示mysql版本:5.7.16
master節點:
slave節點:
建立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
密碼為123456
CREATE 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';
安裝步驟同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檔名稱和OffsetCHANGE 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;
在master上建立test資料庫並建立user表,重新整理檢視salve庫,出現了對應的庫表
經驗證資料同步也沒有問題。
SHOW SLAVE STATUS
時發現 slave_io_running=No salve_sql_running=No
,可能的原因有很多,可以檢視如下的欄位中輸出的內容
可能的原因:
server-id
重複,直接修改對應的id即可auto.cnf
中即可MASTER_LOG_FILE/MASTER_LOG_POS
值設定的有問題,在slave節點上STOP SLAVE;
然後重新連線下master即可在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