2026年7月9日
2026年7月9日
MySQLのレプリケーション設定方法 GTIDでソースとレプリカを構築する手順
MySQL のレプリケーションは、ソース(書き込みを受けるサーバー)のバイナリログをレプリカが読み取り、同じ変更を再生することで、2台のデータベースを同じ状態に保つ仕組みです。この記事では MySQL 8.0 以降を前提に、GTID を使った非同期レプリケーションを1台のソースと1台のレプリカで構築する手順と、動作の確認方法、止まったときの原因の切り分け方を説明します。最後に、WordPress でレプリカをどう活用できるか、何は自動では起きないかも整理します。
始める前に知っておくこと
構文の名前が変わっている
MySQL は 8.0.22 前後から用語を改め、CHANGE MASTER TO は CHANGE REPLICATION SOURCE TO、START SLAVE は START REPLICA、SHOW SLAVE STATUS は SHOW REPLICA STATUS になりました。8.4 系では古い構文の多くが削除されています(2026年10月現在)。古い記事の手順をそのまま打つとエラーになるため、自分のサーバーのバージョンを SELECT VERSION(); で確かめてから進めてください。
MariaDB もレプリケーションに対応していますが、GTID の仕組みと設定の書き方が MySQL と異なります。この記事の手順は MySQL 向けで、MariaDB では公式ドキュメントの手順に従ってください。
レプリケーションはバックアップの代わりにならない
ソースで誤って DROP TABLE や大量の DELETE を実行すると、その操作もレプリカに再生されます。レプリカは「サーバーが壊れたときの予備」や「読み取り負荷の分散」には役立ちますが、「誤操作から戻す」役目は、定期バックアップとバイナリログによる時点復旧が担います。
想定する構成
- ソース: 10.0.0.11(WordPress が接続している既存のサーバー)
- レプリカ: 10.0.0.12(新しく用意したサーバー、同じメジャーバージョンの MySQL)
- 2台は社内ネットワークやクラウドのプライベートネットワークでつながっている
IP アドレスは例です。作業前にソースのバックアップを取り、可能なら検証環境で一度通しておきます。
手順1:ネットワークと設定ファイル
ソースの 3306 番ポートは、レプリカの IP アドレスからだけ接続を許可します。インターネット全体に開けないでください。ソースの bind-address がローカルホストだけになっていると外から接続できないため、プライベート側のアドレスを指定します。
設定ファイルの場所は OS やパッケージで異なり、Ubuntu の公式パッケージでは /etc/mysql/mysql.conf.d/mysqld.cnf、RHEL 系では /etc/my.cnf や /etc/my.cnf.d/ 配下が多いです。
# ソース側 [mysqld]
server_id = 1
log_bin = mysql-bin
gtid_mode = ON
enforce_gtid_consistency = ON
bind-address = 10.0.0.11
# レプリカ側 [mysqld]
server_id = 2
gtid_mode = ON
enforce_gtid_consistency = ON
relay_log = relay-bin
read_only = ON
super_read_only = ON
server_id は2台で異なる値にします。同じだとレプリケーションが正しく動きません。gtid_mode と enforce_gtid_consistency は GTID(トランザクションごとの通し番号)を有効にする設定で、レプリカが「どこまで再生したか」を自動で管理できるようになります。
レプリカの read_only と super_read_only は、レプリカへの誤った書き込みを防ぐ設定です。直接書き込まれるとソースとデータがずれ、再生が止まる原因になります。MySQL 8.0 以降はバイナリログがデフォルトで有効で、形式も行ベース(ROW)です。特別な理由が無ければ変更しないでください。
設定後、両方の MySQL を再起動し、SELECT @@server_id, @@gtid_mode; で反映を確かめます。既存のソースで GTID を後から有効にする場合は、gtid_mode を段階的に切り替える手順が公式に用意されているため、稼働中のサーバーではそちらに従います。
手順2:レプリケーション用のユーザーを作る
ソースで、レプリカが接続するための専用ユーザーを作ります。WordPress 用のユーザーを流用せず、接続元をレプリカの IP に限ります。
-- ソースで実行
CREATE USER 'repl'@'10.0.0.12' IDENTIFIED BY 'your-strong-password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.0.12';
権限名は今も REPLICATION SLAVE です。パスワードは推測されにくい長いものにし、作業メモやチャットに平文で残さないようにします。
手順3:初期データをレプリカに写す
レプリケーションは「開始した時点からの変更」を送る仕組みなので、先にソースの現在のデータをレプリカへ写します。小〜中規模なら mysqldump が手軽です。
# ソースで実行: InnoDB をロックせずに一貫したダンプを取り、GTID の位置も記録する
mysqldump -u root -p --all-databases --single-transaction \
--routines --triggers --events --set-gtid-purged=ON > source-dump.sql
# レプリカへ転送して取り込む
scp source-dump.sql admin@10.0.0.12:/tmp/
mysql -u root -p < /tmp/source-dump.sql
レプリカは手順1で super_read_only を有効にしているため、そのままでは取り込み(書き込み)も拒否されます。取り込みの直前にレプリカで SET GLOBAL super_read_only = OFF; を実行し、取り込みが終わったら SET GLOBAL super_read_only = ON; で戻します(super_read_only を ON にすると read_only も ON になります)。レプリケーションによる再生はこの設定の影響を受けません。
--single-transaction は InnoDB のテーブルを止めずに、ある一時点のデータをそろえて取り出すオプションです。--set-gtid-purged=ON を付けると、ダンプ時点までに実行済みの GTID がダンプに書き込まれ、レプリカは「その続きから受け取ればよい」と分かります。取り込み時に GTID_PURGED に関するエラーが出る場合は、レプリカ側に既に GTID の履歴があることが原因です。新しいレプリカであれば、レプリカ側でだけバイナリログと GTID の履歴を初期化してから取り込み直します(8.0 では RESET MASTER、8.4 では RESET BINARY LOGS AND GTIDS)。ソースでは実行しないでください。
データが大きい場合は、MySQL Shell のダンプ機能や Clone プラグインのほうが速いことがあります(使える機能はバージョンで異なります)。
手順4:レプリケーションを開始する
-- レプリカで実行
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '10.0.0.11',
SOURCE_PORT = 3306,
SOURCE_USER = 'repl',
SOURCE_PASSWORD = 'your-strong-password',
SOURCE_AUTO_POSITION = 1,
SOURCE_SSL = 1;
START REPLICA;
SOURCE_AUTO_POSITION = 1 は GTID で続きの位置を自動的に決める指定です。SOURCE_SSL = 1 は通信を暗号化する指定で、MySQL 8.0 以降のデフォルトの認証方式(caching_sha2_password)は、暗号化された接続か公開鍵の取得を求めるため、これが無いと接続で失敗することがあります。ここで指定したパスワードはレプリカの接続情報として保存されるため、レプリカの管理者権限やデータディレクトリへのアクセスは必要な人に限ります。
手順5:状態を確かめる
SHOW REPLICA STATUS\G
見るべき項目は次のとおりです。
Replica_IO_Running: Yesソースからバイナリログを受け取れているReplica_SQL_Running: Yes受け取った変更を再生できているSeconds_Behind_Sourceレプリカの遅れの目安(秒)。0 か小さい値なら追い付いているLast_IO_ErrorとLast_SQL_Error止まったときの理由
両方が Yes になったら、ソースで CREATE DATABASE repl_test; を実行し、レプリカの SHOW DATABASES; に現れるかを確かめます。確認後はソースで DROP DATABASE repl_test; を実行すれば、削除もレプリカに反映されます。
止まったときの切り分け
Replica_IO_Running が Connecting のまま
ソースに接続できていません。可能性が高い順に、ファイアウォールやセキュリティグループで 3306 番が閉じている、ソースの bind-address が外を受け付けていない、ユーザーの接続元ホストやパスワードが違う、の3つです。レプリカから mysql -h 10.0.0.11 -u repl -p で手動接続してみると、どこで失敗しているかが分かります。Authentication requires secure connection と出る場合は、手順4の SOURCE_SSL = 1 が抜けています。
Replica_SQL_Running が No になった
Last_SQL_Error に Duplicate entry や「行が見つからない」といった内容が出ている場合、ソースとレプリカのデータがずれています。多くはレプリカへの直接の書き込みか、初期データの取り込みの不備が原因です。エラーになったトランザクションを飛ばして再開する方法もありますが、ずれを残したまま進むため、データが正しいか判断できないなら、初期データからレプリカを作り直すほうが安全です。
仮想マシンを複製してレプリカを作った
equal MySQL server UUIDs のようなエラーが出る場合、複製元と同じサーバー UUID を持っています。レプリカのデータディレクトリにある auto.cnf を削除して MySQL を再起動すると、新しい UUID が作られます。server_id の重複も同時に確かめます。
WordPress でレプリカをどう使うか
レプリカを用意しても、WordPress は wp-config.php の DB_HOST に書いた1台にしか接続しません。読み取りを自動でレプリカに振り分ける機能はコアに無いため、活用のしかたは次の3つに分かれます。
- バックアップや重い集計をレプリカで実行し、ソースの負荷を下げる
- ソースが故障したときの予備にする。切り替えは手動で、レプリカで
STOP REPLICA;とRESET REPLICA ALL;を実行し、read_onlyを解除してからDB_HOSTを書き換える - HyperDB や LudicrousDB のようなドロップイン(
wp-content/db.php)で読み書きを分ける。導入前にメンテナンス状況と自分の WordPress のバージョンでの動作を確かめ、保存直後の画面が遅れたデータを表示しないかを検証環境で確認する
Amazon RDS や Aurora などのマネージドサービスでは、リードレプリカの作成をサービス側が受け持つため、この記事の手順は不要です。
まとめ
- MySQL 8.0 以降は
CHANGE REPLICATION SOURCE TO/START REPLICA/SHOW REPLICA STATUSを使う。8.4 では旧構文の多くが使えない server_idを2台で変え、GTID を有効にし、レプリカはread_onlyとsuper_read_onlyで書き込みを防ぐ- 専用ユーザーに
REPLICATION SLAVEを与え、接続元をレプリカの IP に限る。3306 番は外に開けない - 初期データは
--single-transaction --set-gtid-purged=ON付きのダンプで写し、SOURCE_AUTO_POSITION = 1で開始する Replica_IO_RunningとReplica_SQL_RunningがともにYesかを確かめ、止まったらLast_*_Errorを読む- レプリケーションはバックアップの代わりにならない。WordPress の読み書き分離はドロップインが別途必要