個人開発しているサイトのDBをシングルDB構成からレプリケーション構成に変更しました
自分がレプリケーションを設定したことがあるのは、現役時代のMySQL5系だったため、知識のアップデートも兼ねてGTIDベースでレプリケーションを構築してみることにしました
GTIDベースのレプリケーションとは
GTID(Global Transaction ID)ベースのレプリケーションはMySQL5.6.11から利用可能になったレプリケーション方法
それまではバイナリログのポジションを基準にして、GTIDモードではプライマリDBでトランザクションのコミット毎に発行されるIDをベースにレプリケーションを行います
従来のレプリケーション設定時はマスターDBのbin-logやポジションなんかを調べてスレーブに設定する必要がありましたが、GTIDベースではそのような設定も不要となり、設定が大幅に簡略化されるそのこと
やってみる
早速レプリケーションを構成していきます
現在はDockerを利用してインフラを構築しています
レプリケーション構成は以下のようになります
services:
db-primary:
container_name: ride-mysql-primary
image: mysql:9.4
command: >
mysqld
--server-id=1
--log-bin=mysql-bin
--binlog-do-db=ride
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--default-time-zone=Asia/Tokyo
--gtid-mode=ON
--enforce-gtid-consistency=ON
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: db
MYSQL_USER: db_user
MYSQL_PASSWORD: password
ports:
- 3306:3306
volumes:
- './primary-data:/var/lib/mysql'
db-replica:
container_name: ride-mysql-replica
image: mysql:9.4
command: >
mysqld
--server-id=2
--relay-log=mysql-relay-bin
--log-slave-updates=1
--replicate-do-db=db
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--default-time-zone=Asia/Tokyo
--gtid-mode=ON
--enforce-gtid-consistency=ON
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- 3307:3306
volumes:
- './replica-data:/var/lib/mysql'
depends_on:
- db-primarydocker compose up -dで起動すると、db-primary, db-replicaの2つのDBが立ち上がります
プライマリDBのデータレプリカDBに読み込み
プライマリDBのデータをエクスポートします(レプリカDBの初期データとして利用するため)
docker compose exec 出力元DB mysqldump -u root -p --all-databases --single-transaction > backup.sqlレプリカDBにデータベースを作成
# docker-compose.yml があるディレクトリで実行
echo "CREATE DATABASE db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" | docker compose exec -T db-replica mysql -u root -ppasswordデータをインポート
cat backup.sql | docker compose exec -T db-replica mysql -u root -ppasswordレプリケーションの設定
レプリケーションの設定を行います
まずはプライマリDBにレプリケーション専用のユーザーを作成
# docker-compose.yml があるディレクトリで実行
docker compose exec db-primary mysql -u root -ppassword -e "CREATE USER 'replicator'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%'; FLUSH PRIVILEGES;"レプリカDBにレプリケーションの設定を行います
GTIDベースでのレプリケーションのため、CHANGE_MASTER_LOGといったオプションは利用していません
GET_SOURCE_PUBLIC_KEY=1を設定していますが、レプリカDBからプライマリDBに接続する際にセキュアな接続を要求されたため、プライマリDBより公開鍵を取得するために設定しています
echo "CHANGE REPLICATION SOURCE TO SOURCE_HOST='db-primary', SOURCE_USER='replicator', SOURCE_PASSWORD='password', SOURCE_AUTO_POSITION=1, GET_SOURCE_PUBLIC_KEY=1; START REPLICA;" | docker compose exec -T db-replica mysql -u root -ppassword最後にレプリカDBのレプリケーション状態を確認します
echo "SHOW REPLICA STATUS" | docker compose exec -T db-replica mysql -u root -ppassword出力結果の Replica_IO_Running と Replica_SQL_Running が両方 Yesとなっていれば、レプリケーションが開始されています
あとはレプリカDBにデータ参照用のユーザーを設定すれば設定完了です
以上
ざっとですがGTIDベースのレプリケーション構築内容を紹介しました
以前(MySQL 5系)と比較して、確かに簡単に設定できました。特にマスターDBのbin-logやポジションを調査する必要がないのがありがたいですね
今回のケースでは(個人開発のため)DBを気軽に停止できる環境で行いましたが、停止が許されない環境では構築手順は事前に検証する必要があります