MySQL 8.0 升级 8.4:PHP 7.3 + Swoole 4.3 兼容性问题与修复方案
MySQL 8.0 升级至 8.4,属于小版本跨越,但 8.4 是一个 LTS 版本,做了若干破坏性变更。结合 PHP 7.3 + Swoole 4.3 的实际情况,整理出以下兼容性问题和对应处理方案。

影响概览
| 问题 | 严重程度 | 影响范围 |
|---|---|---|
mysql_native_password 插件被移除 | 🔴 高 | 连接直接失败 |
| Swoole 连接池持久连接行为异常 | 🔴 高 | 协程环境下连接错乱 |
ONLY_FULL_GROUP_BY 更严格 | 🟡 中 | 部分查询报错 |
| 新增保留关键字 | 🟡 中 | SQL 语法错误 |
| 废弃配置项导致启动失败 | 🟡 中 | MySQL 无法启动 |
| 默认排序规则变更 | 🟢 低 | JOIN 排序规则冲突 |
问题一:mysql_native_password 插件被正式移除
问题描述
MySQL 8.0 已将默认认证插件改为 caching_sha2_password,但 mysql_native_password 仍作为内置插件保留。8.4 将其彻底移除,不再默认加载,需显式启用。
如果 8.0 时期的用户账号是用 mysql_native_password 创建的,升级 8.4 后连接会直接报错:
mysqli::__construct(): The server requested authentication method unknown |
PHP 7.3 内置的 mysqlnd 版本对 caching_sha2_password 握手协议支持不完整,即使 MySQL 端改了认证方式,PHP 侧也可能无法正确完成握手。
![]()
修复方案
方案 A(应急):在 my.cnf 中重新加载该插件
[mysqld] |
重启 MySQL 后,将存量用户认证方式回写:
ALTER USER 'your_user'@'%' |
方案 B(长期):升级 PHP,使用 caching_sha2_password
PHP 8.1+ 的 mysqlnd 完整支持 SHA-2 认证,升级后可将账号迁移至新认证方式:
ALTER USER 'your_user'@'%' |
问题二:Swoole 4.3 连接池在 MySQL 8.4 下的兼容问题
这是 Swoole 环境特有的问题,也是最容易被忽视的。
2.1 长连接被服务端断开后连接池未感知
MySQL 8.4 对空闲连接的清理更积极,wait_timeout 默认 28800 秒(8小时)。连接池中的空闲连接被 MySQL 服务端单方面断开后,Swoole 4.3 的连接池不能可靠地感知到,下次复用时报:
MySQL server has gone away (errno 2006) |
修复:取出连接时先 ping,或设置连接最大空闲时间
// 取出连接时检测是否存活 |
// 连接池最大空闲时间设为小于 MySQL wait_timeout |
2.2 握手阶段协程切换导致连接状态错乱
Swoole 4.3 对 mysqli 的协程化改造不完整,在 caching_sha2_password 的多步握手过程中,协程切换可能导致连接上下文错乱。具体表现为偶发性认证失败或连接挂起。
修复:强制 mysql_native_password(配合问题一的方案 A),绕过多步握手
单步握手协议下 Swoole 4.3 的行为是稳定的。
2.3 事务状态未清理导致连接污染
协程中开启事务但未正确提交/回滚就归还连接,下一个协程复用该连接时继承了脏状态。MySQL 8.4 对事务隔离级别默认行为有微调,更容易暴露这个问题。
修复:归还连接前强制 rollback
// 归还连接到池之前 |
Swoole 版本对比
| Swoole 版本 | PHP 支持 | mysqli 协程化 | 维护状态 |
|---|---|---|---|
| 4.3 | 7.x | 不完整 | 已停止维护 |
| 4.8 | 7.2 ~ 8.0 | 改进 | 仅安全修复 |
| 5.x | 8.1+ | 完整 | 活跃维护 |
根本解决方案是结合 PHP 升级,将 Swoole 一并升级至 5.x。
问题三:ONLY_FULL_GROUP_BY 执行更严格
问题描述
MySQL 8.0 已开启该模式,8.4 执行更严格。SELECT 中出现未在 GROUP BY 中列出、也未被聚合函数包裹的字段,直接报错:
ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause |

问题写法与修复
-- ❌ username 未聚合 |
在测试环境执行全量回归,通过报错日志逐条定位问题 SQL。
问题四:新增保留关键字
MySQL 8.4 新增了若干保留关键字,若字段名或表名与其重名,SQL 会报语法错误。
常见新增关键字:QUALIFY、ARRAY、VALUE、MEMBER、SYSTEM、INTERSECT、EXCEPT
-- ❌ 字段名为 value |
扫描脚本:
SELECT TABLE_NAME, COLUMN_NAME |
问题五:废弃配置项导致 MySQL 无法启动
query_cache_* 系列参数在 MySQL 8.0 已移除,8.4 中如果 my.cnf 仍保留这些配置,MySQL 启动直接失败。
# ❌ 必须删除 |
# expire_logs_days 已废弃,改用: |
升级前先验证配置文件:
mysqld --validate-config --defaults-file=/etc/mysql/my.cnf |
问题六:默认排序规则变更
MySQL 8.4 新建库/表的默认排序规则为 utf8mb4_0900_ai_ci。旧库用的是 utf8mb4_general_ci,跨库 JOIN 或字符串比较时会报:
ERROR 1267 (HY000): Illegal mix of collations |
由于是 8.0 → 8.4,旧表排序规则不会自动变更,问题通常出现在新建表与旧表 JOIN 时。
-- 查看所有表的排序规则 |
修复执行顺序
第一步:升级前(在 8.0 环境操作)
-- 将所有应用账号改为 mysql_native_password |
# 检查配置文件是否有废弃项 |
第二步:升级 MySQL 至 8.4 后
# my.cnf 加入 |
# 重启后验证连接 |
第三步:业务 SQL 修复
在测试环境全量回归,收集报错 SQL,逐条处理:
- GROUP BY 非完全聚合 → 补字段或 ANY_VALUE()
- 保留关键字冲突 → 加反引号
- 新建表排序规则 → 显式指定 COLLATE
第四步:Swoole 连接池加固
- 加入 ping 存活检测
- 设置连接最大空闲时间 < MySQL
wait_timeout - 归还连接前清理未提交事务
Checklist
升级前
- [ ]
mysqld --validate-config检查配置,删除废弃项 - [ ] 所有应用账号改为
mysql_native_password - [ ] 备份数据库
升级后 MySQL
- [ ]
my.cnf加入mysql_native_password = ON - [ ] 验证 MySQL 正常启动
- [ ] 验证应用连接正常
业务 SQL
- [ ] 扫描 GROUP BY 非完全聚合
- [ ] 扫描保留关键字冲突字段/表名
- [ ] 新建表显式指定排序规则
Swoole 连接池
- [ ] 加入 ping 存活检测
- [ ] 设置连接最大空闲时间 < MySQL
wait_timeout - [ ] 归还连接前执行 rollback 清理事务状态
中期规划
- [ ] PHP 升级至 8.1+,Swoole 升级至 5.x
- [ ] 账号认证迁移至
caching_sha2_password - [ ] 删除
my.cnf中的mysql_native_password = ON




