DockerでMariaDBのリードレプリカを作成する | SEEDS Creators' Blog | 株式会社シーズ

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

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

前回は、Docker環境でMySQLコンテナを2つ用意し、片方をマスターに、片方をリードレプリカにしてみました
今回は、MariaDBで同様のことをやってみたいと思います

注意事項

この記事ではMariaDBのレプリケーションの機能を利用します
レプリケーションについて解説はしませんので、詳しく知りたい方はこちらをご参考ください
https://mariadb.com/kb/en/standard-replication/

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

ファイル構成

最終的にできるファイル構成は下記のようになります
あらかじめファイルを作っておきますと作業が楽になるかと思われます

/
┣ docker/
┃┣ mariadb_source/
┃┃┣ conf.d/
┃┃┃┗ mariadb_source.cnf
┃┃┗ init_data/
┃┃ ┗ 001-GRANT_REPLICATION.sh
┃┗ mariadb_read/
┃ ┣ conf.d/
┃ ┃┗ mariadb_read.cnf
┃ ┗ init_data/
┃  ┗ 001-START_REPLICA.sh
┣ .env
┗ docker-compose.yml

各ファイル編集

/.env

.envには利用するユーザとパスワードを指定します
今回、ユーザは user パスワードは password としておきます
また、rootユーザのパスワードの指定も行います(本記事では password としています)

SOURCE_MYSQL_ROOT_PASSWORD=password

SOURCE_MYSQL_USER=user
SOURCE_MYSQL_PASSWORD=password

/docker-compose.yml

コンテナはMariaDBを2台なので2台分の設定をします
やることは、imageで mariadb:10.6 の指定、 volumes の指定と環境変数の指定のみです
初期で作成するデータベースはマスターにのみ指定しておけばOKです
必要に応じてポート等の設定はしてください

version: '3.8'
services: 
    mariadb_source:
        image: mariadb:10.6
        volumes:
            - ./docker/mariadb_source/conf.d:/etc/mysql/conf.d
            - ./docker/mariadb_source/init_data:/docker-entrypoint-initdb.d
        environment:
            MYSQL_DATABASE: test
            MYSQL_USER: ${SOURCE_MYSQL_USER}
            MYSQL_PASSWORD: ${SOURCE_MYSQL_PASSWORD}
            MYSQL_ROOT_PASSWORD: ${SOURCE_MYSQL_ROOT_PASSWORD}
    mariadb_read:
        image: mariadb:10.6
        volumes:
            - ./docker/mariadb_read/conf.d:/etc/mysql/conf.d
            - ./docker/mariadb_read/init_data:/docker-entrypoint-initdb.d
        environment:
            SOURCE_MYSQL_HOST: mariadb_source
            SOURCE_MYSQL_USER: ${SOURCE_MYSQL_USER}
            SOURCE_MYSQL_PASSWORD: ${SOURCE_MYSQL_PASSWORD}
            SOURCE_MYSQL_ROOT_PASSWORD: ${SOURCE_MYSQL_ROOT_PASSWORD}
            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 … レプリケーションログの名前、無くても動作はします

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

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

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

マスターにはない設定内容は以下の通りです
read_only … 書き込みを不可にする

[mariadb]
server-id=2
read_only

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

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

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

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

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

ここでは

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

を行います

#!/bin/sh
until mysqladmin ping -h$SOURCE_MYSQL_HOST -u$SOURCE_MYSQL_USER -p$SOURCE_MYSQL_PASSWORD --silent; do
    sleep 1
done

mysqldump -h$SOURCE_MYSQL_HOST -uroot -p$SOURCE_MYSQL_ROOT_PASSWORD --all-databases > /tmp/db_dump.db
mysql -uroot -p$MYSQL_ROOT_PASSWORD < /tmp/db_dump.db
rm /tmp/db_dump.db

mysql -uroot -p$MYSQL_ROOT_PASSWORD -e" \
    CHANGE MASTER TO \
        MASTER_HOST = '$SOURCE_MYSQL_HOST', \
        MASTER_PORT = 3306, \
        MASTER_USER = '$SOURCE_MYSQL_USER', \
        MASTER_PASSWORD = '$SOURCE_MYSQL_PASSWORD', \
        MASTER_USE_GTID = slave_pos; \
    START REPLICA; \
"

パーミッションの変更

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

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

ここまでで環境の準備は完了です
docker-compose up で起動させましょう
エラーが発生しなければ問題なく設定できているかと思います

動作確認

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

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

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

MariaDB [test]> CREATE TABLE test(
    -> id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    -> name VARCHAR(255)
    -> );
Query OK, 0 rows affected (0.013 sec)

MariaDB [test]> INSERT INTO `test`(`name`) VALUE ('SampleData');
Query OK, 1 row affected (0.007 sec)

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

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

続いて、データが反映されているかを確認します
リードレプリカのMariaDBサーバに入ります

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

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

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

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

最後に読み込み専用になっているかも確認してみます
INSERTを実行しようとするとエラーが出るはずです

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

最後に

今回はMariaDBでやってみました
MySQLと同様にできるかと思いましたが、そうではなくいろいろと試行錯誤する必要がありました
今後はrootパスワードがランダムでも動かせるようにしていきたいなと思いました

この記事が少しでも参考になればうれしいです
最後までお読みいただきありがとうございました