MySQL 从 5.x 升级到 8.0 后网站出现 Server Error 的解决方法

一、背景

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

问题现象

二、问题现象

  • ✅ 网站首页能正常打开
  • ❌ 点击文章、分类、页面等任何内页,浏览器显示 Server Error500 Internal Server Error
  • ❌ 宝塔面板的数据库恢复功能无效
  • ❌ PHP-FPM 日志显示脚本执行超时
原因分析

三、原因分析

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                |
+--------------------+

第二步:恢复数据库备份

2.1 检查备份文件位置

宝塔面板的数据库备份默认存放在:

ls -la /www/backup/database/

通常路径为:

/www/backup/database/mysql/你的数据库名/备份文件名.sql

2.2 创建空数据库

备份文件需要导入到一个已存在的数据库中,先手动创建数据库:

CREATE DATABASE 你的数据库名 CHARACTER SET utf8 COLLATE utf8_general_ci;

2.3 命令行恢复数据

⚠️ 重要提示:执行宝塔面板的”数据库恢复”功能失效,于是直接改用在命令行恢复。

方式一:直接导入 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

2.4 验证数据完整性

恢复完成后,登录 MySQL 检查数据:

bash
USE 你的数据库名;
SHOW TABLES;
SELECT COUNT(*) FROM 你的主表;  -- 如 wp_posts、users 等

第三步:检查并修复用户认证插件

MySQL 8.0 默认使用 caching_sha2_password,可能导致 PHP 连接失败。

3.1 查看当前认证方式

SELECT user, host, plugin FROM mysql.user WHERE user='你的数据库用户名';

3.2 修改认证方式

如果 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 模式(可选)

如果修改认证方式后仍然报错,检查 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;

第六步:重启 PHP-FPM 和 Nginx

完成所有修改后,重启服务使配置生效:

bash
/etc/init.d/php-fpm-85 restart   # 将 85 替换为你的 PHP 版本号
/etc/init.d/nginx restart

第七步:清除程序缓存

部分 PHP 框架会缓存数据库连接信息,需要清理缓存:

WordPress

  • 方法一:后台安装 WP Optimize 插件清理缓存
  • 方法二:清理 transient:

DELETE FROM wp_options WHERE option_name LIKE '%transient%';


五、查看错误日志

如果在以上步骤中遇到问题,可以通过错误日志定位具体原因:

PHP-FPM 错误日志

tail -50 /www/server/php/85/var/log/php-fpm.log

PHP-FPM 慢日志

tail -50 /www/server/php/85/var/log/php-fpm.log.slow

Nginx 错误日志

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

七、预防建议

升级前务必完整备份

  • 宝塔面板自动备份
  • 命令行手动导出备份
  • 下载备份文件到本地电脑

做好云服务器快照

  • 升级前为系统盘创建快照
  • 出问题可秒级回滚

在测试环境先验证

  • 大版本升级建议先在测试站尝试
  • 确认无误后再操作生产环境

定期检查备份有效性

  • 定期验证备份文件是否可以正常恢复
  • 避免备份文件损坏导致无法恢复

记录数据库连接信息

  • 数据库名、用户名、密码
  • 用户 host(localhost / % / 127.0.0.1)

八 参考命令汇总

MySQL 相关命令

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

九、成功标志

解决完成后,网站应该满足以下状态:

  • ✅ 首页正常访问
  • ✅ 所有内页正常访问
  • ✅ 数据库查询正常
  • ✅ 没有 500 错误
  • ✅ PHP-FPM 日志无严重错误

十、结语

MySQL 跨大版本升级虽然风险较高,但只要按照正确的步骤操作,问题都是可以解决的。关键是要有完整的备份清晰的排查思路

老王于2026-07-31 23:45发布在网页设计
楚客追梦情难休,万里追寻志未酬。
赞助 点赞 1

正在等待第一条评论中

头像预览

发表评论

您的邮箱地址不会被公开, 必填项已用 * 标注

找回密码

请输入您的邮箱地址,我们将向您发送重置密码的链接。

您好,朋友!

请输入相关信息,以便我们提供更优质的服务!

欢迎回来!