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';
若版本、插件或托管限制不明确,停止并交给数据库管理员/服务商。不要直接修改系统账户表、授予宽泛权限或通过重启跳过授权检查。
一次只做一个有界变更
- 确保基线检查结果和回滚点已记录,但日志中没有秘密。除非事件明确是已知的密码不一致,否则基线不健康时先诊断,不要旋转。
- 在批准的秘密管理器中生成并保存新秘密;不要放入 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 运行模型匹配。
验证成功后再关闭回滚窗口
先验证 PHP 语法、数据库连接和 WordPress 安装状态,全程不要使用 --debug 或打印配置:
php -l "$(wp config path)"
wp db query 'SELECT 1;' --skip-column-names --quiet
wp core is-installed --quiet
再从外部请求只读页面,并检查经过遮盖的 PHP、Web、数据库代理、队列和 cron 错误。确认所有副本都使用新秘密,且没有旧凭据的失败重试。多站点和共享用户需要覆盖所有消费者。
若使用 MySQL 8.0.14+ 双密码,只有在观察窗口结束、回滚不再需要后,才由批准的管理员删除第二凭据:
ALTER USER 'WP_APP_USER'@'WP_APP_HOST'
DISCARD OLD PASSWORD;
删除后再次执行只读验证。不要把成功页面缓存当作数据库连接证明。
回滚与恢复门
| 所处阶段 | 安全动作 | 不应做什么 |
|---|---|---|
| 尚未改数据库 | 停止,修正计划或诊断 | 不要为了“试试”而改密码 |
| 双密码已启用、旧凭据仍有效 | 恢复先前配置/秘密版本,验证后调查 | 不要先 DISCARD OLD PASSWORD |
| 单密码已改变、应用失败 | 用交互式客户端判断数据库是否接受新凭据;按批准流程恢复数据库旧凭据和配置 | 不要在两个密码之间反复切换 |
| 旧凭据已删除或遗失 | 保持维护状态,使用服务商/DBA 的账户恢复流程 | 不要启用无授权模式或远程 root |
回滚也属于一次受控密码变更,必须遵守同样的历史、日志、审计和双人复核要求。若备份不可恢复、账户身份不明确或没有合法管理员访问,停止并升级处理。
多站点、容器和托管环境
- WordPress Multisite:一个网络通常共享安装与数据库连接;一次凭据变更可能影响所有子站点。
wp db query的--url不会改变其数据库目标。 - 多个 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 数据库密码的。
