#DBレプリケーションとは
Master DBのデータがSlave DBに同期化されて、同じデータをSlave DBから確認できます。
データの安定性を確保するかつ、書き込みはMaster DB, 読み込みはSlave DBを利用してDBの負荷を下げるために使います。
(最近はMasterやSlaveなどの言葉は使わない方向に進んでいますが)
ディレクトリ構造
docker-compose.yml
version: '3.3'
services:
db-master:
image: mymaster
volumes:
- ./mymaster/mysql-init-files/:/docker-entrypoint-initdb.d/
- ./mymaster/mysql-config-files/:/etc/mysql/conf.d
restart: always
container_name: mymaster
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD="true"
ports:
- '3333:3306'
expose:
- '3333'
db-slave:
image: myslave
volumes:
- ./myslave/mysql-init-files/:/docker-entrypoint-initdb.d/
- ./myslave/mysql-config-files/:/etc/mysql/conf.d
restart: always
container_name: myslave
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD="true"
ports:
- '2222:3306'
expose:
- '2222'
imageとしてmymasterを利用していますが、dockerfileでビルドしたものです。大した内容はありませんのでmysqlのimageを使用しても構いません。
Masterの設定
dockerfile
FROM mysql:5.7
EXPOSE 3306
CMD ["mysqld"]
my.cnf
[mysqld]
log-bin=mysql-bin
server-id=1
log-binはクエリを実行するとき残すログです。
server-idを1として指定します。
create.sql
CREATE DATABASE repl;
CREATE TABLE repl.user(
id VARCHAR(100) PRIMARY KEY,
name VARCHAR (100)
);
create user master@'%' identified by 'master';
grant all privileges on *.* to master@'%' identified by 'master';
grant replication slave on *.* to 'slave'@'%' identified by 'slave';
重要なのは
grant replication slave on *.* to 'slave'@'%' identified by 'slave';
でSlaveからレプリケーションをかけるユーザーを作成することです。
Slave設定
dockerfile
FROM mysql:5.7
EXPOSE 3306
CMD ["mysqld"]
Masterと同じです。
my.cnf
[mysqld]
server-id=2
replicate-do-db='repl'
server-idを2に指定します。
レプリケーションするDBを指定します。
create.sql
CREATE DATABASE repl;
CREATE TABLE repl.user(
id VARCHAR(100) PRIMARY KEY,
name VARCHAR (100)
);
create user slave@'%' identified by 'slave';
grant all privileges on repl.* to slave@'%' identified by 'slave';
レプリケーションのため、Masterと同じテーブルを作成することが必要です。
最後に、シェルスクリプトでレプリケーションを実行します。
レプリケーションの実行
init.sh
#!/bin/sh
#make mymaster image
docker build --no-cache -t mymaster ./mymaster/
#make myslave image
docker build --no-cache -t myslave ./myslave/
docker-compose -f ./docker-compose.yml up -d --remove-orphans
sleep 15s
# macのコマンドですので、Windowsなら他のIPアドレス取得方法が必要です。
myaddress=`ipconfig getifaddr en0`
myaddress=${myaddress}
# Masterのログファイルの場所を取得します。
master_log_file=`mysql -h127.0.0.1 --port 3333 -uroot -e "show master status\G" | grep mysql-bin`
master_log_file="${master_log_file}"
re="[a-z]*-bin.[0-9]*"
if [[ ${master_log_file} =~ $re ]];then
master_log_file=${BASH_REMATCH[0]}
fi
# Masterのポジションも取得します。
master_log_pos=`mysql -h127.0.0.1 --port 3333 -uroot -e "show master status\G" | grep Position`
master_log_pos="${master_log_pos}"
re="[0-9]+"
if [[ ${master_log_pos} =~ $re ]];then
master_log_pos=${BASH_REMATCH[0]}
fi
query="change master to master_host='${myaddress}', master_user='slave', master_password='slave', master_log_file='${master_log_file}', master_log_pos=${master_log_pos}, master_port=3333"
mysql -h127.0.0.1 --port 2222 -uroot -e "${query}"
mysql -h127.0.0.1 --port 2222 -uroot -e "start slave"
init.shを実行するとdockerのimageをビルドして、コンテナー間のレプリケーションをかけます。
これでレプリケーションをかけたmysqlコンテナーができました。