直接改用户认证插件最可靠,因default_authentication_plugin仅在实例初始化时生效,对已有用户无效;真正起效的是mysql.user表中各用户的plugin字段,须用alter user显式设定。

直接改用户认证插件最可靠,ALTER USER ... IDENTIFIED WITH mysql_native_password 是多数场景下见效最快、副作用最小的操作。
为什么不能只改 default_authentication_plugin 配置?
这个配置项只在 MySQL 实例首次初始化时生效,升级后的 8.0 实例再修改 my.cnf 里的 default_authentication_plugin=mysql_native_password,对已有用户完全无效。日志里不报错,但连接照样失败——这是最常白忙活的点。
真正起作用的是每个用户的 plugin 字段值,它存在 mysql.user 视图中,由 ALTER USER 显式设定。
- 查当前用户插件:
SELECT user, host, plugin FROM mysql.user WHERE user = 'your_user'; - 新创建的用户会继承该配置,但已有用户不会自动更新
- Docker 环境里如果反复重建容器,可以靠启动参数
--default-authentication-plugin控制,但宿主机或云数据库上没这机会
ALTER USER 操作要注意哪些坑?
看似一条命令就能解决,实际执行时容易卡在权限、语法或密码策略上:
- 必须用有
CREATE USER或UPDATE权限的账号登录,普通应用账号不行 - 主机名要严格匹配,
'root'@'localhost'和'root'@'%'是两个不同用户,远程连接得改后者 - MySQL 8.0 默认启用强密码策略,如果原密码太弱(比如
123456),ALTER USER会直接拒绝,得先用一个符合策略的密码临时更新再改插件 - 语句末尾不能漏掉
BY 'password',否则会清空密码(不是保留原密码)
Java/JDBC 连不上?光加参数没用,驱动版本是硬门槛
很多文档教你在连接 URL 里加 ?defaultAuthenticationPlugin=mysql_native_password 或 ?allowPublicKeyRetrieval=true,但这只是“辅助开关”。核心问题是:旧版 mysql-connector-java:5.1.x 根本没有实现 caching_sha2_password 协议逻辑,连握手流程都解析不了。
- 必须升级到
mysql:mysql-connector-java:8.0.33+(Maven 坐标) - 连接 URL 至少带
?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false - 如果服务端已强制要求 SSL,
useSSL=false会失败,得配好证书或改服务端require_secure_transport=OFF - Spring Boot 2.4+ 默认拉取 8.0+ 驱动,但老项目手动引入 5.1.x 的,得主动排除旧依赖
Navicat/SQLyog/ODBC 这类图形工具怎么选?
这类工具自带嵌入式驱动,版本绑定死,升级比改数据库配置还麻烦。优先级建议:
- 能升到 Navicat 15.0.8+、SQLyog 13.1.7+、ODBC 8.0+ 驱动的,直接升级——一劳永逸,还能用上新特性
- 受限于许可证或内网策略无法升级的,就改用户插件,别碰全局配置
- 批量处理多个用户时,别手敲
ALTER USER,用脚本从mysql.user查出所有plugin != 'mysql_native_password'的行,生成语句批量执行 - PHP 的
mysqli扩展若报SQLSTATE[HY000] [2054],确认是否用了老版mysqlnd,Linux 发行版源里的包常滞后,建议编译安装新版
安全和兼容从来不是非此即彼的选择,而是分层控制:服务端用 caching_sha2_password 保底线,客户端按能力分级适配,中间靠明确的用户级配置桥接——模糊地带最容易出问题。











