背景
- フレームワークを自作する夢はある
- Laravelは美しくシンプルなライブラリをいっぱい取り入れている
- Laravel採用した優秀なライブラリをすべて単体で使ってみる
- 今回はORMライブラリのEloquentを使ってみる
- まずはEloquentのmasterとslaveを切り替えを実現したい
- Docker上でMySQLレプリケーション環境を構築する必要がある(本編)
前提
- レプリケーション用専用ネットワークを構築する
- MySQLデータの永続化
サーバー構成
192.168.0.11 → master用サーバー
192.168.0.12 → slave用サーバー
ディレクトリ構成
├── docker
│ └── db
│ ├── init
│ │ ├── 001_schema.sql
│ │ ├── 002_sample.sql
│ │ └── start-slave.sh
│ ├── master.cnf
│ └── slave.cnf
└── docker-compose.yml
master.cnf
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
expire_logs_days=5
log-bin=mysql-bin
server-id=200
slave.cnf
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
expire_logs_days=5
server-id=201
read_only=1
start-slave.sh
#!/bin/sh
# masterをロック
mysql -u root -h master -e "RESET MASTER;"
mysql -u root -h master -e "FLUSH TABLES WITH READ LOCK;"
# master情報をdump
mysqldump -u root -h master --all-databases --master-data --single-transaction --flush-logs --events > /tmp/master_dump.sql
# slaveにimport
mysql -u root -e "STOP SLAVE;";
mysql -u root < /tmp/master_dump.sql
# bin-logのファイル名とポジションを取得
log_file=`mysql -u root -h master -e "SHOW MASTER STATUS\G" | grep File: | awk '{print $2}'`
pos=`mysql -u root -h master -e "SHOW MASTER STATUS\G" | grep Position: | awk '{print $2}'`
# slave開始
mysql -u root -e "RESET SLAVE;";
mysql -u root -e "CHANGE MASTER TO MASTER_HOST='master', MASTER_USER='repl', MASTER_PASSWORD='Zaq1Zaq1', MASTER_LOG_FILE='${log_file}', MASTER_LOG_POS=${pos};"
mysql -u root -e "START SLAVE;"
# masterをunlockする
mysql -u root -h master -e "UNLOCK TABLES;"
001_schema.sql
CREATE USER 'repl'@'192.168.0.12' IDENTIFIED BY 'Zaq1Zaq1';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.0.12';
FLUSH PRIVILEGES;
DROP TABLE IF EXISTS `blog`;
CREATE TABLE `blog` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT 'タイトル',
PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='ブログ';
※ slaveサーバーのip_addressを指定すること
※ レプリケーション用ユーザー名情報を指定すること
docker-compose.yml
version: '3'
services:
master:
container_name: blog-db-master
image: mysql:5.7
ports:
- "63306:3306"
volumes:
- blog-data:/var/lib/mysql # masterはvolumeをmount(永続化させる)
- ./docker/db/master.cnf:/etc/mysql/conf.d/master.cnf
networks:
blog_network:
ipv4_address: 192.168.0.11
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE=db_blog
- MYSQL_USER=db_blog
- MYSQL_PASSWORD=Zaq1Zaq1
- TZ=Asia/Tokyo
slave:
container_name: blog-db-slave
image: mysql:5.7
ports:
- '63307:3306'
depends_on:
- master
tmpfs: /var/lib/mysql
volumes:
- ./docker/db/slave.cnf:/etc/mysql/conf.d/slave.cnf
- ./docker/db/init/start-slave.sh:/docker-entrypoint-initdb.d/start-slave.sh
networks:
blog_network:
ipv4_address: 192.168.0.12
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE=db_blog
- MYSQL_USER=db_blog
- MYSQL_PASSWORD=Zaq1Zaq1
- TZ=Asia/Tokyo
volumes:
blog-data:
driver: 'local'
networks:
blog_network:
driver: bridge
ipam:
config:
- subnet: 192.168.0.0/24
初回
docker-compose build
docker-compose up master
docker exec -i blog-db-master mysql -r db_blog < docker/db/init/001_schema.sql
docker exec -i blog-db-master mysql -r db_blog < docker/db/init/002_sample.sql
docker-compose up slave
docker-compose stop
docker-compose up -d
Pool overlaps with other one on this address space
上記のエラー出る場合は、ip_address空間や、ホストのip_address空間と重複している可能性があるので、
docker-compose.ymlに指定した「networks:」の「subnet」を違うアドレスに変更してみてください。
次回以降
docker-compose up -d
参考
https://qiita.com/takyam/items/f13bc4a1db0433ffb958
https://qiita.com/Butterthon/items/e85825d3eff6559a1cf1
ソースコードはこちら
https://github.com/horityabiriko/docker-mysql-replication