











今天又手欠在宝塔面板中将MySQL从5.4升级到8.0,升级完就一阵心慌,因为发现网站首页可以正常访问,但点击任何内页都会出现 Server Error(500 错误)。好在有AI,经过一番排查,终于解决了问题。当然如果解决不了也没关系,大不了重新装回旧版。现将完整的解决过程记录下来,后续再遇到类似问题可以自己解决,不用问AI走太多弯路。

Server Error 或 500 Internal Server Error
MySQL 5.x 升级到 8.0 是一个跨大版本升级,变化较大,主要涉及以下几个方面:
| 问题类型 | 说明 |
|---|---|
| 身份认证插件变更 | MySQL 8.0 默认使用 caching_sha2_password,PHP 7.1 及以下版本不支持 |
| SQL 模式更严格 | 8.0 默认启用了 ONLY_FULL_GROUP_BY 等严格模式 |
| 默认字符集变更 | 8.0 默认字符集为 utf8mb4_0900_ai_ci,与旧版本不兼容 |
| 数据丢失 | ⚠️ 本次问题的核心原因:升级后数据库被删除或丢失 |

登录 MySQL,查看当前数据库列表:
TEXT
mysql -u root -p
SHOW DATABASES;
预期结果:如果只看到以下 4 个系统数据库,说明业务数据库已丢失:
TEXT
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
宝塔面板的数据库备份默认存放在:
ls -la /www/backup/database/
通常路径为:
/www/backup/database/mysql/你的数据库名/备份文件名.sql
备份文件需要导入到一个已存在的数据库中,先手动创建数据库:
CREATE DATABASE 你的数据库名 CHARACTER SET utf8 COLLATE utf8_general_ci;
⚠️ 重要提示:执行宝塔面板的”数据库恢复”功能失效,于是直接改用在命令行恢复。
方式一:直接导入 SQL 文件
mysql -u root -p 你的数据库名 < /www/backup/database/mysql/名称/备份文件路径.sql
方式二:导入压缩包(.gz)
gunzip -c 备份文件.sql.gz | mysql -u root -p 你的数据库名
方式三:强制导入(忽略错误)
mysql -u root -p --force 你的数据库名 < 备份文件.sql
恢复完成后,登录 MySQL 检查数据:
bash
USE 你的数据库名;
SHOW TABLES;
SELECT COUNT(*) FROM 你的主表; -- 如 wp_posts、users 等
MySQL 8.0 默认使用 caching_sha2_password,可能导致 PHP 连接失败。
SELECT user, host, plugin FROM mysql.user WHERE user='你的数据库用户名';
如果 plugin 显示为 caching_sha2_password,执行以下命令修改:
bash
ALTER USER '你的数据库用户名'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';
FLUSH PRIVILEGES;
注意:如果
host不是localhost(如%或127.0.0.1),请相应修改。
示例:
bash
ALTER USER 'wanghao'@'localhost' IDENTIFIED WITH mysql_native_password BY 'mypassword123';
FLUSH PRIVILEGES;
如果修改认证方式后仍然报错,检查 SQL 模式是否过于严格:
SELECT @@sql_mode;
如果包含 ONLY_FULL_GROUP_BY,可以临时放宽:
bash
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
永久修改(修改配置文件):
vi /etc/my.cnf
在 [mysqld] 段落下添加:
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
保存后重启 MySQL:
/etc/init.d/mysqld restart
确认数据库字符集与程序兼容:
bash
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME = '你的数据库名';
如有需要,修改数据库字符集:
ALTER DATABASE 你的数据库名 CHARACTER SET utf8 COLLATE utf8_general_ci;
完成所有修改后,重启服务使配置生效:
bash
/etc/init.d/php-fpm-85 restart # 将 85 替换为你的 PHP 版本号
/etc/init.d/nginx restart
部分 PHP 框架会缓存数据库连接信息,需要清理缓存:
DELETE FROM wp_options WHERE option_name LIKE '%transient%';
如果在以上步骤中遇到问题,可以通过错误日志定位具体原因:
tail -50 /www/server/php/85/var/log/php-fpm.log
tail -50 /www/server/php/85/var/log/php-fpm.log.slow
tail -50 /www/wwwlogs/你的域名.error.log
MySQL 跨大版本升级(5.x → 8.0)是一个高风险操作,常见问题及解决方法如下:
| 问题类型 | 现象 | 解决方法 |
|---|---|---|
| 数据库丢失 | SHOW DATABASES; 看不到业务数据库 |
命令行恢复备份 |
| 认证插件不兼容 | PHP 无法连接 MySQL | 修改为 mysql_native_password |
| SQL 模式过于严格 | 某些 SQL 查询报错 | 移除 ONLY_FULL_GROUP_BY |
| 字符集不兼容 | 中文乱码或查询报错 | 修改为 utf8_general_ci |
| 程序缓存 | 修改后仍报错 | 清理缓存目录 |
| 服务未重启 | 配置未生效 | 重启 PHP-FPM 和 Nginx |
bash
# 登录 MySQL
mysql -u root -p
# 查看所有数据库
SHOW DATABASES;
# 创建数据库
CREATE DATABASE 数据库名 CHARACTER SET utf8 COLLATE utf8_general_ci;
# 查看表
USE 数据库名;
SHOW TABLES;
# 查看数据量
SELECT COUNT(*) FROM 表名;
# 查看用户认证方式
SELECT user, host, plugin FROM mysql.user;
# 修改认证方式
ALTER USER '用户名'@'localhost' IDENTIFIED WITH mysql_native_password BY '密码';
FLUSH PRIVILEGES;
# 查看 SQL 模式
SELECT @@sql_mode;
# 修改 SQL 模式
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
# 查看字符集
SHOW VARIABLES LIKE 'character_set%';
bash
# 导入 SQL 文件
mysql -u root -p 数据库名 < /path/to/backup.sql
# 导入 gz 压缩文件
gunzip -c backup.sql.gz | mysql -u root -p 数据库名
# 强制导入(忽略错误)
mysql -u root -p --force 数据库名 < backup.sql
bash
# 重启 PHP-FPM(PHP 8.5)
/etc/init.d/php-fpm-85 restart
# 重启 Nginx
/etc/init.d/nginx restart
# 重启 MySQL
/etc/init.d/mysqld restart
bash
# PHP-FPM 错误日志
tail -50 /www/server/php/85/var/log/php-fpm.log
# Nginx 错误日志
tail -50 /www/wwwlogs/你的域名.error.log
# 实时监控日志
tail -f /www/server/php/85/var/log/php-fpm.log
解决完成后,网站应该满足以下状态:
MySQL 跨大版本升级虽然风险较高,但只要按照正确的步骤操作,问题都是可以解决的。关键是要有完整的备份和清晰的排查思路。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。