本文约 3,080 字,预计阅读 8 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:数据库一升级,站点就”建立连接时出错”
最常见的翻车现场:数据库升级完成,MySQL 服务正常运行,命令行能登录,但 WordPress 前台显示”建立数据库连接时出错”。
原因通常不是数据库没起来,而是认证插件换了——MySQL 8 默认 caching_sha2_password,而老版本 PHP 的 mysqli 扩展不支持它。
原理分析:MySQL 8 的三个关键变化
| 变化 | 影响 |
|---|---|
默认认证插件改为 caching_sha2_password |
老客户端/PHP 连不上 |
默认字符集改为 utf8mb4,排序规则 utf8mb4_0900_ai_ci |
与旧库的 utf8mb4_unicode_ci 混用可能导致排序异常、索引问题 |
新增保留字(如 rank、row、groups、system) |
字段名与保留字冲突时 SQL 报错 |
| 查询缓存被移除 | 原本依赖 Query Cache 的站点可能感觉变慢 |
WordPress 本身对 MySQL 8 支持良好(官方最低要求 MySQL 5.7 / MariaDB 10.4),问题基本出在客户端兼容和迁移过程。
保姆级实操
第一步:升级前检查 PHP 与 mysqli 版本
php -r 'echo mysqli_get_client_info(), PHP_EOL;'
php -i | grep -i "Client API library version"
支持 caching_sha2_password 需要:
- PHP 7.4+ 且 mysqlnd 8.0.16+(libmysqlclient 则需 8.0.16+);
- 或者干脆切回
mysql_native_password。
第二步:检查现有字符集
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'wordpress';
SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'wordpress';
如果库/表是 utf8mb4_unicode_ci 而新服务器默认 utf8mb4_0900_ai_ci,跨库 JOIN 或字符串比较会报:
Illegal mix of collations
统一处理(推荐保持 unicode_ci,兼容性最好):
ALTER DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
逐表转换见第 046 篇的字符集专题。
第三步:备份(导出兼容性要注意)
mysqldump -u root -p --default-character-set=utf8mb4 --single-transaction \
--routines --triggers --events wordpress > wp-before-mysql8.sql
--single-transaction 保证一致性且不加锁,生产环境必加。
第四步:升级 MySQL
# Ubuntu 22.04 默认已是 MySQL 8 / MariaDB 10.6
sudo apt install -y mysql-server-8.0
sudo mysql_upgrade # MySQL 8.0.16 之后该步骤已并入服务启动
第五步:修复认证问题(关键)
如果 WordPress 报连接错误,两种解法:
方案一:改用户认证方式(最快)
ALTER USER 'wpuser'@'localhost'
IDENTIFIED WITH mysql_native_password BY '密码';
FLUSH PRIVILEGES;
方案二:确认 PHP 支持后保持 sha2
ALTER USER 'wpuser'@'localhost'
IDENTIFIED WITH caching_sha2_password BY '密码';
并在 my.cnf 里确保:
[mysqld]
default_authentication_plugin=mysql_native_password # 如需兼容老客户端
第六步:检查保留字冲突
升级后如果某些插件报错 You have an error in your SQL syntax,检查是否有字段叫 rank、row、groups、system、json_value 等:
SELECT DISTINCT COLUMN_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='wordpress'
AND COLUMN_NAME IN ('rank','row','groups','system','lead','lag','json_value');
命中则需要改字段名或用反引号包裹(插件层改动,需联系作者)。
第七步:调整参数
MySQL 8 移除了查询缓存,把相关参数删掉,否则启动报错:
; 删除这些(MySQL 8 不支持)
; query_cache_type
; query_cache_size
调整 InnoDB 缓冲池(按内存 60%~70%):
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M
max_connections = 200
第八步:验证 WordPress
wp db check
wp db optimize
wp option get home
常见踩坑与失败案例
- 只改了 root 的认证方式,没改 wpuser —— WordPress 用的是
wp-config.php里的用户,改错对象等于没改。 - 案例:某站升级后前台正常,但后台某统计插件报错。排查发现插件建表时用了
rank字段名,MySQL 8 将其列为保留字。最后升级插件版本解决。 mysqldump导出后导入报排序规则错误 —— 目标库不支持utf8mb4_0900_ai_ci(比如导入到 MariaDB)。导出时用--compatible或手工替换排序规则。- 性能反而下降 —— 8.0 早期版本在某些查询上有性能回归,且查询缓存被移除。建议开启 Redis 对象缓存补偿。
- 升级不可逆 —— MySQL 8 降级回 5.7 需要 dump/reload,无法原地降级。一定要先备份。
总结
MySQL 8 迁移的三道关卡是认证插件、排序规则、保留字。升级流程:先确认 PHP 客户端支持 → 备份 → 升级 → 修认证 → 检查排序规则与保留字 → 调参数 → 验证。如果你用的是老版本 PHP 或不方便改认证,MariaDB 10.6/10.11 是更省事的替代路线(兼容 mysql_native_password,与 MySQL 5.7 行为接近)。无论选哪个,升级前那次 mysqldump 都是你唯一的后悔药。
