2026年7月12日
2026年7月12日
WordPressでAmazon RDS Proxyを使ってDB接続数を抑える設定と注意点
Amazon RDS Proxy は、WordPress(PHP)と RDS/Aurora の間に入り、DB への接続をプールして使い回すマネージドサービスです。Web サーバーが増減する構成や、アクセス急増時に「Too many connections」が出る構成で効果があります。この記事では、RDS Proxy が向いているかどうかの判断、作成から wp-config.php の切り替えまでの手順、そして WordPress 特有の「ピン留め」の問題と確認方法を説明します。
WordPress の DB 接続はどう増えるのか
WordPress は、PHP のリクエストごとに DB へ新しく接続し、処理が終われば切断します。持続的な接続は既定では使いません。そのため、同時に DB へつながる数はおおよそ「同時に動いている PHP プロセスの数 × Web サーバーの台数」になります。
たとえば PHP-FPM の pm.max_children が 50 の Web サーバーを、オートスケーリングで 10 台まで増やせる構成なら、最大 500 前後の接続が一斉に DB に向かう可能性があります。DB 側の max_connections を超えるとエラーになり、超えなくても接続の確立そのものが DB の CPU とメモリを消費します。
RDS Proxy は、アプリからの多数の接続(クライアント接続)を受け止め、DB へは少数の接続(データベース接続)を維持して使い回します。これにより、DB が直接受ける接続数と、接続確立の負荷を抑えられます。また、Aurora や Multi-AZ 構成のフェイルオーバー時に、アプリ側の接続を保ったまま新しいプライマリーへ切り替える助けにもなります。
RDS Proxy が向いている構成・向いていない構成
導入前に、本当に接続数がボトルネックかを確認します。CloudWatch で RDS の DatabaseConnections を見て、max_connections に近づく場面があるか、接続数の急増と同時にエラーが出ていないかを調べてください。
向いているのは次のような構成です。
- Web サーバーをオートスケーリングで増減させている
- アクセスの急増時に接続数が跳ね上がり、DB 側でエラーが出る
- フェイルオーバー時の停止時間を短くしたい
一方、次の場合は RDS Proxy では解決しません。
- 遅いクエリが原因で DB の CPU が高い(スロークエリの改善が先です)
- Web サーバー 1 台で接続数に余裕がある(追加の経路と費用が増えるだけです)
- そもそも PHP 側が処理しきれていない
接続数を減らす手段は RDS Proxy だけではありません。PHP-FPM の同時実行数を DB の許容量に合わせる、ページキャッシュやオブジェクトキャッシュ(Redis など)でクエリそのものを減らす、といった対策のほうが先に効くことも多いので、あわせて検討してください。
RDS Proxy を作成する
RDS Proxy の対応エンジンやバージョン、機能の範囲は更新されることがあります(2026年10月現在)。作業の前に AWS の公式ドキュメントで、利用中の RDS for MySQL / Aurora MySQL のバージョンが対応しているかを確認してください。
事前に用意するもの
- DB の認証情報を AWS Secrets Manager に保存する: RDS Proxy は、DB へ接続するユーザー名とパスワードを Secrets Manager から読み取ります。WordPress 用 DB ユーザーの情報をシークレットとして登録します。
- IAM ロール: RDS Proxy がそのシークレットを読み取るための権限を持つロールを用意します。コンソールから作成すると自動で作る選択肢が出ることがあります。
- ネットワーク: RDS Proxy は VPC 内に作られ、インターネットからは接続できません。Web サーバーと同じ VPC か、接続できるネットワークに置きます。セキュリティグループは「Web サーバー → Proxy のポート 3306」「Proxy → DB のポート 3306」が通るように設定します。
AWS CLI で作成する例
コンソールからでも作成できますが、手順を記録に残しやすい AWS CLI の例を示します。名前、ARN、サブネット、セキュリティグループは自分の環境の値に置き換えてください。
# Proxy を作成(TLS を必須にする)
aws rds create-db-proxy \
--db-proxy-name wp-proxy \
--engine-family MYSQL \
--auth '[{"AuthScheme":"SECRETS","SecretArn":"arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:wp-db-secret","IAMAuth":"DISABLED"}]' \
--role-arn arn:aws:iam::123456789012:role/wp-proxy-role \
--vpc-subnet-ids subnet-aaaa1111 subnet-bbbb2222 \
--vpc-security-group-ids sg-0123abcd \
--require-tls
# 接続先の DB を登録(Aurora の場合は --db-cluster-identifiers を使う)
aws rds register-db-proxy-targets \
--db-proxy-name wp-proxy \
--db-instance-identifiers wp-db
作成には数分かかります。状態が利用可能になったら、Proxy のエンドポイント名を控えます。
接続プールの設定
ターゲットグループの接続プール設定で、DB の max_connections のうち何割まで Proxy が使うかを決めます。
aws rds modify-db-proxy-target-group \
--db-proxy-name wp-proxy \
--target-group-name default \
--connection-pool-config MaxConnectionsPercent=80,MaxIdleConnectionsPercent=40,ConnectionBorrowTimeout=120
MaxConnectionsPercent を 100 にすると、管理作業や監視用の接続の余地がなくなります。バックアップや mysql コマンドで直接 DB に入る余裕を残すため、少し下げておくのが安全です。ConnectionBorrowTimeout は、空きの接続が無いときにクライアントを待たせる秒数で、これを超えるとクライアントにエラーが返ります。
WordPress を Proxy 経由に切り替える
wp-config.php のバックアップを取ったうえで、まずステージング環境で DB_HOST を Proxy のエンドポイントに変更します。
define( 'DB_HOST', 'wp-proxy.proxy-abcdefghijkl.ap-northeast-1.rds.amazonaws.com' );
// Proxy で TLS を必須にした場合
define( 'MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL );
DB_USER と DB_PASSWORD は、Secrets Manager に登録したものと同じ値です。接続できない場合は、セキュリティグループ、Proxy と同じ VPC から到達できるか、TLS の設定の順に確認します。
切り替えた直後に、管理画面へのログイン、投稿の保存、画像のアップロード、フォーム送信などの書き込みを伴う操作を一通り試してください。
ピン留め(session pinning)を確認する
RDS Proxy の効果を左右するのが「ピン留め」です。クライアントがセッション固有の状態を作ると、Proxy はそのクライアントと DB 接続の組を固定し、他のクライアントと共有できなくなります。固定が多いと、接続を使い回す効果はほとんど失われます。
WordPress はこの点で注意が必要です。wpdb は接続のたびに文字コードを設定し、DB の sql_mode に WordPress と相性の悪いモードが含まれていると SET SESSION sql_mode を実行します。MySQL 8.0 の既定の sql_mode には該当するモードが含まれているため、何もしないと毎回の接続で SET 文が実行されます。プラグインが一時テーブルやロック関数を使う場合も固定の原因になります。
確認には CloudWatch の RDS Proxy のメトリクスを使います。
ClientConnections: WordPress から Proxy への接続数DatabaseConnections: Proxy から DB への接続数DatabaseConnectionsCurrentlySessionPinned: 固定されている DB 接続の数
DatabaseConnectionsCurrentlySessionPinned が DatabaseConnections とほぼ同じなら、ほとんどの接続が固定されています。Proxy の拡張ログ(デバッグ用のログ出力)を一時的に有効にすると、固定の理由が記録されるので原因を特定できます。拡張ログは大量に出力されることがあるため、確認が済んだら無効に戻します。
対策として考えられるのは次の方法です。
- パラメータグループの sql_mode を見直す: WordPress が自分で外すモード(
ONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES、NO_ZERO_DATEなど)を、DB 側の設定から先に外しておくと、wpdb が SET 文を送らなくなります。他のアプリが同じ DB を使っている場合は影響を確認してください。 - セッション固定フィルターを使う: MySQL 系では、変数の設定による固定を除外する
EXCLUDE_VARIABLE_SETSというフィルターを指定できます。ただし、あるクライアントが設定した変数が別のクライアントに引き継がれる可能性があり、すべてのクライアントが同じ設定を送ることが前提になります。WordPress 以外のアプリが同じ Proxy を使う場合は慎重に判断してください。 - プラグインを見直す: 一時テーブルや
GET_LOCK()を多用するプラグインがあれば、別の方法に置き換えられないか検討します。
導入後に見るべき指標
切り替え後は、少なくとも数日間、次の点を比較します。
- DB 側の
DatabaseConnectionsが切り替え前より減ったか - ページの応答時間が悪化していないか(Proxy を経由する分、わずかな遅延が加わります)
QueryDatabaseResponseLatencyなどのレイテンシ系メトリクスに異常が無いか- エラーログに接続タイムアウトが出ていないか
効果が見られない場合は、ピン留めの割合と、そもそも接続数が問題だったのかを見直してください。元に戻すときは、wp-config.php の DB_HOST を DB のエンドポイントに戻すだけで済みます。
まとめ
- WordPress はリクエストごとに DB へ接続するため、接続数は PHP プロセス数と Web サーバーの台数に比例して増える
- RDS Proxy は接続をプールして DB の負荷とフェイルオーバー時の影響を抑えるが、遅いクエリや PHP の処理不足は解決しない
- 作成には Secrets Manager の認証情報、IAM ロール、VPC 内のネットワーク設定が必要で、WordPress 側は
DB_HOSTの変更で切り替えられる - WordPress の SET 文などでピン留めが起きると効果が薄れるため、
DatabaseConnectionsCurrentlySessionPinnedで確認し、sql_mode の見直しなどで対処する - 変更はステージングで試し、wp-config.php のバックアップと戻し方を用意してから本番に適用する