2026年7月9日
2026年7月9日
WordPressのデータベースレプリケーションを設定する方法|MySQLのソース・レプリカ構成と読み書き分離
WordPressのデータベースレプリケーションは、MySQL側で「ソース(書き込みを受ける側)」と「レプリカ(複製を受け取る側)」を構成し、WordPressは基本的にソースへ接続したまま使うのが最も手堅い形です。読み込みをレプリカに振り分けたい場合は、HyperDB系のドロップインやProxySQLなどを別途組み合わせます。この記事では、MySQL 8.4 を例に GTID を使ったレプリケーションの設定手順と、WordPress側の接続方法、監視と切り替えの考え方を解説します(2026年10月現在)。
レプリケーションで何が得られるか
レプリケーションは、ソースで実行された変更をバイナリログ経由でレプリカに送り、同じ内容を再現する仕組みです。WordPressで導入する目的は、主に次の3つです。
- 障害時の待機系:ソースが壊れても、レプリカを昇格させれば短時間で復旧できます。
- バックアップの負荷を逃がす:バックアップをレプリカで取れば、ソースの応答速度に影響しにくくなります。
- 読み込みの負荷分散:読み込みのクエリをレプリカに振り分けます。
ただし、レプリケーションはバックアップの代わりにはなりません。誤って記事を削除した操作も、そのままレプリカに複製されます。
また、WordPress本体には読み込みと書き込みを別のサーバーに振り分ける機能がなく、wp-config.php の DB_HOST は1つだけです。まずは「待機系とバックアップ用」として導入し、読み込み分散は必要になってから検討する順番をおすすめします。
前提と用語
ここでは次の構成を例にします。IPアドレスは自分の環境に置き換えてください。
- ソース:
10.0.0.10(WordPressが現在接続しているDBサーバー) - レプリカ:
10.0.0.11(新しく用意するDBサーバー) - データベース名:
wordpress
MySQL 8.0 の途中から、用語が「マスター/スレーブ」から「ソース/レプリカ」に変わり、コマンドも CHANGE REPLICATION SOURCE TO・START REPLICA・SHOW REPLICA STATUS に移りました。MySQL 8.4 では SHOW MASTER STATUS などの古い構文は使えません。MariaDB は独自のGTIDと従来の構文を使うため、この記事の手順はそのままでは当てはまりません。
作業はソースの設定変更と再起動を含みます。事前に mysqldump などでデータベースのバックアップを取り、作業時間帯をアクセスの少ない時間に設定してください。
手順1:ソース側の設定
ソースの MySQL 設定ファイル(Ubuntu なら /etc/mysql/mysql.conf.d/mysqld.cnf など、環境によって異なります)の [mysqld] セクションに次を追加します。
[mysqld]
server_id = 1
log_bin = mysql-bin
gtid_mode = ON
enforce_gtid_consistency = ON
bind-address = 10.0.0.10
server_idはサーバーごとに異なる値にします。同じ値だと複製が始まりません。log_binでバイナリログを有効にします(MySQL 8.x では既定で有効ですが、名前を明示しておくと管理しやすくなります)。gtid_modeとenforce_gtid_consistencyで GTID(トランザクションごとの通し番号)を有効にします。レプリカが「どこまで受け取ったか」を自動で管理するため、ログファイル名と位置を手で指定せずに済みます。bind-addressはレプリカから接続できるアドレスにします。127.0.0.1のままだと外部から接続できません。
設定したら MySQL を再起動し、ファイアウォールで 3306番ポートをレプリカのIPアドレスからだけ許可します。インターネット全体に3306番を開けないでください。
次に、レプリケーション専用のユーザーを作ります。
CREATE USER 'repl'@'10.0.0.11' IDENTIFIED BY 'your-strong-password' REQUIRE SSL;
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.0.11';
権限名は今も REPLICATION SLAVE のままです。接続元をレプリカのIPに限定し、REQUIRE SSL で暗号化された接続だけを許可しています。WordPressが使っているDBユーザーとは別のユーザーにしてください。
手順2:レプリカ側の設定
レプリカにも MySQL をインストールし、設定ファイルに次を追加して再起動します。ソースと同じメジャーバージョン(またはそれより新しいバージョン)にしておくとトラブルが起きにくくなります。
[mysqld]
server_id = 2
log_bin = mysql-bin
relay_log = relay-bin
gtid_mode = ON
enforce_gtid_consistency = ON
read_only = ON
super_read_only = ON
read_only と super_read_only は、レプリカに誤って書き込まないための設定です。レプリカに直接書き込むとソースとの内容がずれ、複製が止まる原因になります。レプリケーションによる反映はこの設定があっても行われます。
手順3:初期データをコピーする
レプリケーションは「設定した時点以降の変更」を送る仕組みなので、開始前にソースのデータをレプリカに写しておく必要があります。ソースで次のように書き出します。
# ソースで実行: ロックを最小限にして WordPress のDBを書き出す
mysqldump -u root -p --single-transaction --routines --triggers --events \
--databases wordpress > wordpress.sql
--single-transaction を付けると、InnoDBのテーブルを一貫した状態で、サイトを止めずに書き出せます。GTIDが有効なサーバーでは、ダンプファイルに「ここまでのトランザクションは適用済み」という情報(GTID_PURGED)が自動で含まれ、レプリカはその続きから受け取ります。
ファイルをレプリカに転送し、読み込みます。
# レプリカで実行
mysql -u root -p < wordpress.sql
ここで「GTID_EXECUTED が空でないため GTID_PURGED を設定できない」という趣旨のエラーが出ることがあります。レプリカ側ですでに何らかの操作(ユーザー作成など)を行い、レプリカ独自のGTIDが記録されている場合です。新しく用意したレプリカであれば、レプリカ側で RESET BINARY LOGS AND GTIDS;(MySQL 8.0 では RESET MASTER;)を実行してから読み込み直します。このコマンドはバイナリログを消すため、ソースでは実行しないでください。
ソースに WordPress 以外のデータベースがあると、レプリカに無いデータベースへの変更が届いて複製が止まることがあるため、DBサーバーはWordPress専用にしておくと扱いやすくなります。
手順4:レプリケーションを開始する
レプリカで、接続先のソースを指定して開始します。
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '10.0.0.10',
SOURCE_USER = 'repl',
SOURCE_PASSWORD = 'your-strong-password',
SOURCE_AUTO_POSITION = 1,
SOURCE_SSL = 1;
START REPLICA;
SHOW REPLICA STATUS\G
SOURCE_AUTO_POSITION = 1 が GTID を使って自動で位置を合わせる指定です。SHOW REPLICA STATUS\G の結果で、次の項目を確認します。
Replica_IO_Running: YesとReplica_SQL_Running: Yes:両方 Yes なら複製が動いています。Seconds_Behind_Source:ソースからどれだけ遅れているかの目安です。通常は 0 か小さい値になります。Last_IO_Error/Last_SQL_Error:止まっている場合はここに原因が出ます。接続エラーならユーザー・パスワード・ファイアウォール・bind-addressを、SQLエラーなら初期データの不一致を疑います。
最後に、ソースで記事を1件下書き保存し、レプリカの wp_posts テーブルに反映されるかを見ると、実際に動いていることを確認できます。
WordPress側の接続をどうするか
待機系・バックアップ用として使う(推奨)
wp-config.php は変更せず、WordPressはソースにだけ接続します。レプリカはバックアップ取得と障害時の切り替え用に使います。WordPress側に変更がないので、プラグインとの相性問題も起きません。
読み込みをレプリカに振り分ける
読み込みを分散したい場合は、wp-content/db.php に置くドロップインで WordPress のデータベース接続クラスを置き換える方法があります。代表的なのが Automattic の HyperDB と、その派生の LudicrousDB です。設定ファイルでソースを書き込み・読み込み用、レプリカを読み込み専用として登録します。HyperDB の設定例は次のような形です。
<?php
// db-config.php(HyperDB の設定ファイル)
$wpdb->add_database( array(
'host' => '10.0.0.10',
'user' => DB_USER,
'password' => DB_PASSWORD,
'name' => DB_NAME,
'write' => 1,
'read' => 1,
) );
$wpdb->add_database( array(
'host' => '10.0.0.11',
'user' => DB_USER,
'password' => DB_PASSWORD,
'name' => DB_NAME,
'write' => 0,
'read' => 1,
) );
この場合、WordPressのDBユーザーをレプリカにも作っておく必要があります(ソースで作ればレプリケーションで複製されます)。また、ドロップインは開発状況や対応バージョンが変わることがあるので、導入前に配布元の最新情報を確認してください。
読み込み分散で欠かせないのがレプリケーションの遅延への配慮です。記事を保存した直後にレプリカから読むと、まだ反映されていない古いデータが表示されることがあります。HyperDB系には、同じリクエスト内で書き込みをした後は読み込みもソースに送る仕組みがありますが、管理画面はソースだけに接続させるなど、運用側でも余裕を持たせておくと安全です。WordPressを変更したくない場合は、ProxySQL のようなプロキシでSELECT文だけをレプリカに送る方法もあります。
監視と障害時の切り替え
レプリケーションは、止まっても WordPress 側では気づきにくいのが難点です。定期的に状態を確認する仕組みを用意します。
# レプリカで実行: 複製の状態と遅延だけを抜き出す(認証は ~/.my.cnf などで設定)
mysql -e "SHOW REPLICA STATUS\G" \
| grep -E "Replica_IO_Running:|Replica_SQL_Running:|Seconds_Behind_Source:|Last_IO_Error:|Last_SQL_Error:"
これを cron で定期実行し、No が含まれる場合や遅延が大きい場合に通知するようにしておくと、停止に早く気づけます。監視ツールを使っているなら、同じ項目を監視対象に加えます。
ソースが壊れたときは、レプリカで複製を止めて書き込み可能にし、WordPressの接続先を切り替えます。
-- レプリカで実行(ソースが復旧しないと判断した後)
STOP REPLICA;
RESET REPLICA ALL;
SET GLOBAL super_read_only = OFF;
SET GLOBAL read_only = OFF;
その後 wp-config.php の DB_HOST をレプリカのアドレスに変更し、設定ファイルの read_only も外します。古いソースが復旧しても、そのまま書き込みを受け付けさせると2台のデータが食い違うため、新しいレプリカとして作り直します。切り替え手順はテスト環境で一度通しておくのが理想です。
まとめ
- レプリケーションは MySQL 側で設定し、WordPress はまずソースに接続したまま、レプリカを待機系とバックアップ用に使う形が手堅い構成です。
- MySQL 8.4 では
CHANGE REPLICATION SOURCE TO/START REPLICA/SHOW REPLICA STATUSを使い、GTID とSOURCE_AUTO_POSITION = 1で位置合わせを自動化します。 - 初期データは
mysqldump --single-transactionで写し、レプリカはread_onlyとsuper_read_onlyで保護します。 - 読み込み分散は HyperDB 系のドロップインや ProxySQL で行い、レプリケーション遅延を前提に設計します。
- レプリケーションはバックアップの代わりにならないので、定期バックアップと状態監視を併用します。