hero_picture
Cover Image for DockerでMariaDBのリードレプリカを作成する

DockerでMariaDBのリードレプリカを作成する

2021/08/31

Webサイト構築事業部の西村です

前回は、Docker環境でMySQLコンテナを2つ用意し、片方をマスターに、片方をリードレプリカにしてみました

今回は、MariaDBで同様のことをやってみたいと思います

注意事項

この記事ではMariaDBのレプリケーションの機能を利用します

レプリケーションについて解説はしませんので、詳しく知りたい方はこちらをご参考ください

https://mariadb.com/kb/en/standard-replication/

また、当記事では開発用途を想定しているためレプリケーション専用のユーザの作成等をしていません

ファイル構成

最終的にできるファイル構成は下記のようになります

あらかじめファイルを作っておきますと作業が楽になるかと思われます

1/
2┣ docker/
3┃┣ mariadb_source/
4┃┃┣ conf.d/
5┃┃┃┗ mariadb_source.cnf
6┃┃┗ init_data/
7┃┃ ┗ 001-GRANT_REPLICATION.sh
8┃┗ mariadb_read/
9┃ ┣ conf.d/
10┃ ┃┗ mariadb_read.cnf
11┃ ┗ init_data/
12┃  ┗ 001-START_REPLICA.sh
13┣ .env
14┗ docker-compose.yml

各ファイル編集

/.env

.envには利用するユーザとパスワードを指定します

今回、ユーザは user パスワードは password としておきます

また、rootユーザのパスワードの指定も行います(本記事では password としています)

1SOURCE_MYSQL_ROOT_PASSWORD=password
2
3SOURCE_MYSQL_USER=user
4SOURCE_MYSQL_PASSWORD=password

/docker-compose.yml

コンテナはMariaDBを2台なので2台分の設定をします

やることは、imageで mariadb:10.6 の指定、 volumes の指定と環境変数の指定のみです

初期で作成するデータベースはマスターにのみ指定しておけばOKです

必要に応じてポート等の設定はしてください

1version: '3.8'
2services: 
3    mariadb_source:
4        image: mariadb:10.6
5        volumes:
6            - ./docker/mariadb_source/conf.d:/etc/mysql/conf.d
7            - ./docker/mariadb_source/init_data:/docker-entrypoint-initdb.d
8        environment:
9            MYSQL_DATABASE: test
10            MYSQL_USER: ${SOURCE_MYSQL_USER}
11            MYSQL_PASSWORD: ${SOURCE_MYSQL_PASSWORD}
12            MYSQL_ROOT_PASSWORD: ${SOURCE_MYSQL_ROOT_PASSWORD}
13    mariadb_read:
14        image: mariadb:10.6
15        volumes:
16            - ./docker/mariadb_read/conf.d:/etc/mysql/conf.d
17            - ./docker/mariadb_read/init_data:/docker-entrypoint-initdb.d
18        environment:
19            SOURCE_MYSQL_HOST: mariadb_source
20            SOURCE_MYSQL_USER: ${SOURCE_MYSQL_USER}
21            SOURCE_MYSQL_PASSWORD: ${SOURCE_MYSQL_PASSWORD}
22            SOURCE_MYSQL_ROOT_PASSWORD: ${SOURCE_MYSQL_ROOT_PASSWORD}
23            MYSQL_RANDOM_ROOT_PASSWORD: 1

/docker/mariadb_source/conf.d/mariadb_source.cnf

レプリケーションに必要な設定を記述します

設定の必要な項目は下記に記載があります

https://mariadb.com/kb/en/setting-up-replication/

各設定項目の内容です

log-bin … バイナリログの有効化

server-id … サーバの識別子 / 0以外でかつ一意しておく必要がある

log-basename … レプリケーションログの名前、無くても動作はします

1[mariadb]
2log-bin
3server-id=1
4log-basename=master

/docker/mariadb_read/conf.d/mariadb_read.cnf

リードレプリカ側の必要な設定です

マスターにはない設定内容は以下の通りです

read_only … 書き込みを不可にする

1[mariadb]
2server-id=2
3read_only

/docker/mariadb_source/init_data/001-GRANT_REPLICATION.sh

ここではリードレプリカからマスターに接続を許可するユーザを指定します

また、RESET MASTER を実行しておきます

RESET MASTER … バイナリログリセットする、これを実行しなければコンテナ起動時にエラーが発生します

1#!/bin/sh
2mysql -uroot -p$MYSQL_ROOT_PASSWORD -e" \
3    RESET MASTER;
4    GRANT REPLICATION SLAVE ON *.* TO '$MYSQL_USER'@'%'; \
5"

/docker/mariadb_read/init_data/001-START_REPLICA.sh

ここでは

  1. マスターの起動を確認
  2. マスターのデータをダンプし取り込む
  3. マスターの設定
  4. レプリケーション開始

を行います

1#!/bin/sh
2until mysqladmin ping -h$SOURCE_MYSQL_HOST -u$SOURCE_MYSQL_USER -p$SOURCE_MYSQL_PASSWORD --silent; do
3    sleep 1
4done
5
6mysqldump -h$SOURCE_MYSQL_HOST -uroot -p$SOURCE_MYSQL_ROOT_PASSWORD --all-databases > /tmp/db_dump.db
7mysql -uroot -p$MYSQL_ROOT_PASSWORD < /tmp/db_dump.db
8rm /tmp/db_dump.db
9
10mysql -uroot -p$MYSQL_ROOT_PASSWORD -e" \
11    CHANGE MASTER TO \
12        MASTER_HOST = '$SOURCE_MYSQL_HOST', \
13        MASTER_PORT = 3306, \
14        MASTER_USER = '$SOURCE_MYSQL_USER', \
15        MASTER_PASSWORD = '$SOURCE_MYSQL_PASSWORD', \
16        MASTER_USE_GTID = slave_pos; \
17    START REPLICA; \
18"

パーミッションの変更

下記の2つのファイルに関して、実行権限を付与しておく必要があるため、パーミッション変更します

  • /docker/mariadb_source/init_data/001-GRANT_REPLICATION.sh
  • /docker/mariadb_read/init_data/001-START_REPLICA.sh
1chmod +x docker/mariadb_source/init_data/001-GRANT_REPLICATION.sh docker/mariadb_read/init_data/001-START_REPLICA.sh

ここまでで環境の準備は完了です

docker-compose up で起動させましょう

エラーが発生しなければ問題なく設定できているかと思います

動作確認

まず、マスターのMariaDBサーバに入ります

1docker-compose exec mariadb_source mysql -uuser -ppassword -Dtest

そしてテーブルを作成し、データを入れてみます

1MariaDB [test]> CREATE TABLE test(
2    -> id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
3    -> name VARCHAR(255)
4    -> );
5Query OK, 0 rows affected (0.013 sec)
6
7MariaDB [test]> INSERT INTO `test`(`name`) VALUE ('SampleData');
8Query OK, 1 row affected (0.007 sec)

データの追加ができたら SELECT で確認しておきます

1MariaDB [test]> SELECT * FROM `test`;
2+----+------------+
3| id | name       |
4+----+------------+
5|  1 | SampleData |
6+----+------------+
71 row in set (0.001 sec)

続いて、データが反映されているかを確認します

リードレプリカのMariaDBサーバに入ります

1docker-compose exec mariadb_read mysql -uuser -ppassword -Dtest

その後先ほどと同じ SELECT を実行します

1MariaDB [test]> SELECT * FROM `test`;
2+----+------------+
3| id | name       |
4+----+------------+
5|  1 | SampleData |
6+----+------------+
71 row in set (0.001 sec)

すると正常にデータが反映されていることがわかります

最後に読み込み専用になっているかも確認してみます

INSERTを実行しようとするとエラーが出るはずです

1MariaDB [test]> INSERT INTO `test`(`name`) VALUE ('ReplicaData');
2ERROR 1290 (HY000): The MariaDB server is running with the --read-only option so it cannot execute this statement

最後に

今回はMariaDBでやってみました

MySQLと同様にできるかと思いましたが、そうではなくいろいろと試行錯誤する必要がありました

今後はrootパスワードがランダムでも動かせるようにしていきたいなと思いました

この記事が少しでも参考になればうれしいです

最後までお読みいただきありがとうございました