直接改用户认证方式最稳,用ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password BY 'pwd';并FLUSH PRIVILEGES;该操作最快生效、影响最小,且必须显式指定插件与密码,仅SET PASSWORD无效。

MySQL 8.0 默认用 caching_sha2_password,老客户端(比如旧版 JDBC、PHP mysqli、Python MySQLdb)连不上,报错 Plugin caching_sha2_password could not be loaded 或 Client does not support authentication protocol——直接改用户认证方式最稳,别先动全局配置。
ALTER USER 切换单个用户的认证插件
这是最快生效、影响最小的修复方式。旧用户不会自动继承新默认插件,必须显式重置。
-
ALTER USER必须带IDENTIFIED WITH mysql_native_password,只写SET PASSWORD不会改插件,密码哈希格式还是旧的 - 主机名要完全匹配,比如建用户时是
'app_user'@'localhost',这里就不能写'app_user'@'%';查当前定义用SELECT User, Host FROM mysql.user; - 执行后必须跟
FLUSH PRIVILEGES;,否则部分 MySQL 8.0 版本(尤其某些云 RDS)不立即生效 - 如果用户 host 是
localhost,本地连接可能因 socket 解析失败,可临时试127.0.0.1验证是否纯插件问题
my.cnf 全局修改 default_authentication_plugin(仅限可控服务器)
适合你完全掌控数据库服务器、且确认所有客户端能兼容或后续会升级的场景。云数据库(如阿里云 RDS、腾讯云 CDB)通常禁用此操作。
- 配置必须放在
[mysqld]段下,写在[client]或其他段无效 - 值设为
mysql_native_password,不是sha256_password或空字符串 - 改完必须
sudo systemctl restart mysqld(不是reload),否则不生效 - 注意:该设置只影响新创建的用户,已有用户仍需单独
ALTER USER
客户端侧绕过方案(不推荐长期使用)
某些驱动支持连接参数临时适配,但有副作用,仅作调试用。
- JDBC 加
?allowPublicKeyRetrieval=true&useSSL=false可让旧驱动走 RSA 密钥交换,但关闭 SSL 会暴露明文凭证 - PHP mysqli 无法通过 DSN 参数切换插件,必须升级到 mysqli 8.0+ 或改服务端用户插件
-
~/.my.cnf里加[client] default_authentication_plugin=mysql_native_password只影响本地命令行客户端,不影响应用代码
为什么不能只升级驱动?要看实际依赖链
你以为升级 JDBC 就万事大吉?未必。很多老项目依赖的中间件(如旧版 Druid、HikariCP、Laravel DBAL)内部封装了驱动版本,表面升级 JDBC JAR,实际加载的仍是包内嵌的老驱动。
- 检查运行时真实加载的驱动类:
SELECT @@version_compile_os, @@version_compile_machine;不管用,得看 JVM 的ClassLoader日志或jstack输出 - Python 项目用
pip list | grep mysql看的是mysql-connector-python或PyMySQL,但 Django 默认用mysqlclient,三者认证逻辑不同 - Node.js 的
mysql2从 v2.0+ 才支持caching_sha2_password,v1.x 即使打补丁也难彻底兼容
真正容易被忽略的点是:MySQL 8.0 对 localhost 的解析更严格,127.0.0.1 和 localhost 在权限表里算两个不同 host,切插件时别漏掉其中一个。


















