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 の読み書き分離はドロップインが別途必要

お気軽にご相談ください

お見積りへ お問い合わせへ
▲