2026年メンテナンス注記:
Error establishing a database connectionは症状であり、パスワード誤りの証明ではありません。認証情報のローテーションを決める前に、読み取り専用で診断します。この手順は権限を持つサイト管理者向けです。マネージドデータベースでは、サービス事業者のコントロールプレーンと手順を優先してください。
Table of Contents
まず二つの変更を区別する
データベース認証情報と WordPress 設定は別の状態であり、意図的に一致させる必要があります。
| レイヤー | 役割 | 代表的な場所 | ロールバック対象 |
|---|---|---|---|
| MySQL/MariaDB | 正確な 'user'@'host' アカウントを認証 | データベースまたは管理コントロールプレーン | 以前の認証情報または第二認証情報 |
| WordPress | 接続パラメーターをデータベースへ渡す | wp-config.php、環境変数、秘密管理ツール | 以前の設定バージョン |
DB_PASSWORD の更新はデータベース側のパスワードを変更しません。データベース側の変更も WordPress を自動更新しません。DB_PASSWORD は専用の最小権限アプリケーションユーザー用であり、データベースの root やリモート管理者用ではありません。
変更前:復旧地点を作る
- 対象サイト、データベースインスタンス、WordPress ルート、担当者、メンテナンス時間帯を確認します。想定影響を明示し、データベースへ書き込むデプロイ、キュー、定期処理を一時停止します。
- 復元テスト済みの既存手順でデータベースバックアップまたはマネージドスナップショットを取得します。暗号化、保持期間、復旧担当者を確認し、暗号化されていない SQL dump を Web ルートへ置かないでください。
- 実際に読み込まれる設定を特定します。
wp-config.phpは WordPress の一つ上のディレクトリにある場合も、環境変数やコンテナ秘密だけを読む場合もあります。 - Web ルート外のアクセス制限された場所へ設定をバックアップし、先に PHP 構文を確認します。
config_path="$(wp config path)"
umask 077
cp -- "$config_path" '/secure/backup/wp-config.php.before-rotation'
php -l "$config_path"
バックアップにも現在の秘密が含まれます。認証情報として保護し、保持ポリシーに従って破棄してください。例のパスが環境に適さなければ停止し、管理プラットフォームまたはデプロイシステムのバックアップ機構を使います。公開読み取り可能なコピーを即席で作らないでください。
変更前:現在の接続を読み取り専用で確認する
秘密ではない設定だけを確認します。wp config list を実行したり、DB_PASSWORD を読み出したり貼り付けたりしないでください。秘密が端末、セッション記録、チケットへ出力される可能性があります。
wp config path
wp config has DB_PASSWORD
wp config get DB_NAME --type=constant
wp config get DB_USER --type=constant
wp config get DB_HOST --type=constant
次に、WordPress が実際に読み込む設定で最小限の読み取り専用クエリを実行します。
wp db query 'SELECT 1;' --skip-column-names --quiet
WordPress とクライアント接続を分けて試す場合は、クライアントに対話的にパスワード入力させます。-p や --password にパスワード値を付けないでください。
mysql --user='WP_APP_USER' --password
--host='DB_HOST' --port=3306
--database='WP_DATABASE' --execute='SELECT 1;'
事業者が Unix socket を明示的に要求する場合は、指定されたパスを別に試します。
mysql --user='WP_APP_USER' --password
--socket='/path/from-provider/mysql.sock'
--database='WP_DATABASE' --execute='SELECT 1;'
- 両方成功:現在の認証情報は有効です。一度の汎用エラーだけでローテーションせず、断続的なネットワーク、リソース枯渇、アプリケーション層を調べます。
- クライアントは成功、WP-CLI は失敗:実際の設定ファイル、PHP 解析、環境変数、コンテナ秘密、PHP データベースドライバー、実行ユーザーを確認します。
- 両方失敗:先にデータベースサービス、ネットワーク、エンドポイント、アカウント、認証情報の問題を分類します。現在のパスワードが不明でも、本番アカウントを闇雲にリセットしないでください。
パスワードを推測せず、エラー種別で診断する
| 症状 | 最初に確認 | 停止条件 |
|---|---|---|
Access denied | 正確なユーザー名、クライアント送信元ホスト、パスワード、ロック/期限切れ、認証プラグイン | 回避目的で 'user'@'%' を作成したり root へ切り替えたりしない |
Connection refused / timeout | データベースプロセス、リスナー、ポート、ファイアウォール、セキュリティグループ、プロキシ、経路 | 「テスト」としてデータベースポートを全世界へ公開しない |
| socket ファイルなし | DB_HOST が socket を選ぶか、PHP とクライアントの socket パス | 存在しないパスを任意の socket へリンクしない |
Unknown database | DB_NAME、インスタンス/テナント、大文字小文字、デプロイ環境 | 問題を覆う空データベースを作らない |
| DNS または TLS エラー | 管理エンドポイント、DNS、CA、証明書名、クライアントの TLS 能力 | 証明書検証を無効化したり通信をダウングレードしたりしない |
| クライアントがプラグイン非対応 | サーバー認証プラグイン、PHP/mysqli/mysqlnd またはプロキシのバージョン | 旧認証プラグインを全体で再有効化しない |
localhost と 127.0.0.1 は同等とは限りません。前者は Unix socket、後者は通常 TCP を選びます。リモートエンドポイントではポート、DNS、プロキシ、検証済み TLS が必要な場合もあります。WordPress 公式の`DB_HOST` 説明にはホスト、ポート、socket の形式がありますが、実際の値は事業者またはデプロイ設定から取得してください。
正確なアカウントと最小権限を確認する
MySQL/MariaDB アカウントはユーザー名とクライアントホストで識別されます。データベースが見る送信元は、ブラウザー利用者ではなく Web ノード、コンテナサブネット、プロキシかもしれません。リモート root ではなく、既存の管理された管理者アカウントで接続します。リモート接続には事業者指定の証明書検証オプションも加えてください。
MYSQL_HISTFILE=/dev/null mysql
--user='DB_ADMIN_USER' --password
--host='DB_ADMIN_ENDPOINT'
生の出力を記録・共有しない管理セッションで、識別情報、バージョン、既存プラグイン、権限だけを確認します。チケットへ載せる前にホスト、スキーマ、アカウント名を伏せ、パスワードハッシュを照会・複製しないでください。
SELECT CURRENT_USER(), @@version, @@version_comment;
SHOW GRANTS FOR 'WP_APP_USER'@'WP_APP_HOST';
SELECT User, Host, plugin FROM mysql.user WHERE User = 'WP_APP_USER';
アプリケーションユーザーが WordPress データベースに必要な既存権限だけを保持していることを確認します。パスワード障害は権限再設計の時間ではありません。グローバルな ALL 権限の付与、ワイルドカード送信元の管理者作成、システムアカウントテーブルの直接編集は行わないでください。
バージョン確認済みのローテーション経路を選ぶ
次の優先順位を使います。
- 管理コントロールプレーン:事業者が認証情報ローテーション、秘密のバージョン、ブルーグリーン切替を提供するなら、その手順を使います。SQL テンプレートは適用できない場合があります。
- MySQL 8.0.14+ の二重パスワード:正確なサーバーバージョン、認証プラグイン、管理者権限が
RETAIN CURRENT PASSWORD/DISCARD OLD PASSWORDに対応するときだけ使います。旧パスワードを一時的な第二認証情報として残し、アプリケーションを戻せます。 - 単一パスワード切替:MariaDB、旧 MySQL、外部認証プラグイン、二重パスワード非対応環境では、メンテナンス時間帯と密な調整が必要です。同じバージョンの非本番環境で事前演習してください。
以下は構文テンプレートであり、実際の秘密ではありません。秘密管理ツールの値への置換は、クライアント履歴無効、--syslog/--log-raw なし、端末録画なし、サーバー監査ポリシー適合を満たす承認済みセッションだけで行います。
MySQL 8.0.14+ の二重パスワード用テンプレートです。EXISTING_AUTH_PLUGIN が対象アカウントの現在の対応プラグインであることを公式文書で先に確認します。
ALTER USER 'WP_APP_USER'@'WP_APP_HOST'
IDENTIFIED WITH EXISTING_AUTH_PLUGIN
BY 'REPLACE_WITH_NEW_SECRET'
RETAIN CURRENT PASSWORD;
二重パスワードを使わない場合、MySQL 8.x のパスワード型プラグインでは次のテンプレートを使えます。旧パスワードは直ちに無効になります。
ALTER USER 'WP_APP_USER'@'WP_APP_HOST'
IDENTIFIED WITH EXISTING_AUTH_PLUGIN
BY 'REPLACE_WITH_NEW_SECRET';
MariaDB は認証構文とプラグイン挙動が異なります。対象バージョンの公式 `ALTER USER` 文書で、アカウントがパスワード保存型プラグインを使うと確認できた場合だけ次を検討します。unix_socket、PAM、GSSAPI などの外部認証には使えません。
ALTER USER 'WP_APP_USER'@'WP_APP_HOST'
IDENTIFIED BY 'REPLACE_WITH_NEW_SECRET';
バージョン、プラグイン、管理上の制限が不明なら停止し、DBA/事業者へエスカレーションします。システムアカウントテーブルの直接変更、広範な権限付与、権限確認を飛ばすモードでの再起動を試さないでください。
一度に一つの限定的変更だけを行う
- 秘密を含めずに基準状態とロールバック地点を記録します。既知のパスワード不一致でない限り、不健康な基準状態はローテーション前に診断します。
- 承認済み秘密管理ツールで新しい秘密を生成・保管します。shell 変数、プロセス引数、チャット、クリップボード履歴、スクリーンショット、チケットへ置かないでください。
- 上記からバージョンに合う一経路を選び、正確な
'WP_APP_USER'@'WP_APP_HOST'を一度だけ変更します。プラグイン、権限、ホスト範囲、TLS ポリシーを同時に変えないでください。 - WordPress の実際の設定源を直ちに更新します。同じアカウントを共有する全プロセス、ノード、副本を一つのデプロイ計画へ含めます。
- ランタイムが環境変数やマウント済み秘密をキャッシュする場合だけ、プラットフォーム手順でローリング更新します。データベースを不用意に再起動しないでください。
- 読み取り専用検証を行い、Web、キュー、cron を観察します。失敗したらさらにパスワードを推測せず、ロールバック門へ進みます。
秘密を漏らさず WordPress 側を更新する
一般的な wp-config.php は次の構造です。プレースホルダーは使用可能な認証情報ではありません。
define( 'DB_NAME', 'WP_DATABASE' );
define( 'DB_USER', 'WP_APP_USER' );
define( 'DB_PASSWORD', 'REPLACE_WITH_SECRET_FROM_APPROVED_STORE' );
define( 'DB_HOST', 'DB_HOST[:PORT_OR_SOCKET]' );
環境変数または秘密マウントを既に読む構成なら、その設計を維持します。例:
define( 'DB_PASSWORD', getenv( 'WORDPRESS_DB_PASSWORD' ) );
この障害中に秘密配布方式を再設計しないでください。安全なエディター、秘密管理ツール、デプロイシステムで原子的に更新します。wp config edit でファイルを開けますが、実際の秘密を wp config set のコマンドライン引数に渡してはいけません。後で既存の所有者と最小読み取り権限を復元します。WordPress のハードニングガイドは、互換性のある環境で wp-config.php を必要な利用者/サービスだけが読めるようにすること(一般例は 400 または 440)を勧めますが、実際の PHP 実行モデルに合わせる必要があります。
ロールバック期間を閉じる前に検証する
--debug や設定出力を使わず、PHP 構文、データベース接続、WordPress インストール状態を確認します。
php -l "$(wp config path)"
wp db query 'SELECT 1;' --skip-column-names --quiet
wp core is-installed --quiet
次に外部から読み取り専用ページを要求し、秘密を伏せた PHP、Web、データベースプロキシ、キュー、cron のエラーを確認します。全副本が新しい秘密を使い、旧認証情報で再試行する利用者がいないことを確認してください。Multisite と共有ユーザーでは全利用者を検証します。
MySQL 8.0.14+ の二重パスワードを使った場合、観察期間が終了しロールバック不要になってから、承認済み管理者が第二認証情報を削除します。
ALTER USER 'WP_APP_USER'@'WP_APP_HOST'
DISCARD OLD PASSWORD;
その後もう一度読み取り専用検証を行います。キャッシュされた成功ページはデータベース接続の証明ではありません。
ロールバックと復旧の判断門
| 段階 | 安全な対応 | してはいけないこと |
|---|---|---|
| データベース未変更 | 停止し、計画または診断を修正 | 「試す」ためだけにパスワードを変える |
| 二重パスワード有効、旧認証情報も有効 | 以前の設定/秘密バージョンへ戻し、検証後に調査 | 先に DISCARD OLD PASSWORD を実行 |
| 単一パスワード変更後、アプリ失敗 | 対話プロンプトのクライアントで新認証情報の受理を判定し、承認手順で旧データベース認証情報と設定を復元 | 二つのパスワードを何度も切り替える |
| 旧認証情報を削除または紛失 | メンテナンスを維持し、事業者/DBA のアカウント復旧手順を使用 | 権限迂回モードやリモート root を有効化 |
ロールバック自体も管理されたパスワード変更であり、同じ履歴、ログ、監査、二者確認の管理が必要です。バックアップが復元不能、アカウント識別が不明、正規管理者アクセスがない場合は停止してエスカレーションしてください。
Multisite、コンテナ、マネージド環境
- WordPress Multisite:ネットワークは通常、一つのインストールとデータベース接続を共有するため、一回の認証情報変更が全サブサイトへ影響し得ます。
--urlはwp db queryのデータベース対象を変えません。 - 複数 WordPress インスタンス:別インストールが一つのデータベースユーザーを共有する場合があります。設定値を出力して利用者を探さず、ローテーション前にデプロイ一覧と秘密参照を棚卸しします。
- コンテナ/Kubernetes:秘密の源を変更し全副本をローリング更新します。置換予定の一時コンテナだけを編集しないでください。旧 Pod、worker、cron が終了したことを確認します。
- マネージドホスティング/クラウドデータベース:エンドポイント、CA、プロキシ、許可送信元、ローテーション API、復旧方法はプラットフォームが定義します。汎用 SQL でコントロールプレーンを迂回しないでください。
- プロキシ/読み書き分離/高可用性:WordPress が実際に使うエンドポイントを試します。主系への直接接続成功は、プロキシ、DNS、読み取り副本の正常性を証明しません。
公式資料
- WordPress:`wp-config.php` と `DB_HOST` の編集
- WordPress:一般的なデータベース接続エラー
- WordPress:ハードニングと `wp-config.php` の権限
- WP-CLI:`wp db query`と`wp db check`
- WP-CLI:`wp config`と`wp db export`
- MySQL 8.0:`ALTER USER` と二重パスワード
- MySQL 8.4:アカウント名、認証プラグイン、パスワードのログ
- MySQL 8.4:暗号化接続
- MariaDB:`ALTER USER`と安全な接続
2011 年の原文資料(現行手順ではありません)
以下に source_export の可視本文を完全に保存し、行末空白だけを正規化しています。重要な同期原則を記録していますが、現在の安全なローテーション、接続経路、バージョン差、ロールバック要件を扱っていないため、単独で本番手順には使えません。
MySQL改密码, WordPress无法连接数据库
当你更改 MySQL 密码之后,也要更改 WordPress 根目录里的 wp-config.php 文件里安装时所保存的 MySQL 密码为当前的 MySQL 密码,不然密码都错误,那怎么会连接得上数据库呢。这个没有那么智能的,你不去更改,它是不会知道你改了 MySQL 数据库密码的。
