LoginSignup
17
0

More than 3 years have passed since last update.

背景

  • フレームワークを自作する夢はある
  • 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

17
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
0