90%的连接失败是客户端不兼容caching_sha2_password插件所致;最稳解法是执行alter user切换目标用户认证方式并立即flush privileges,需严格匹配host(如'localhost'/'127.0.0.1'/'%')、带密码重置、且注意navicat等工具缓存问题。

直接结论:90% 的连接失败不是密码错了,而是客户端不认 caching_sha2_password 插件;最稳的解法是执行 ALTER USER 切换目标用户的认证方式,并立刻 FLUSH PRIVILEGES。
怎么确认真是认证插件惹的祸
先登录 MySQL 命令行(用还能连上的账号,比如 root):
- 运行
SELECT user, host, plugin FROM mysql.user WHERE user = 'your_username';—— 注意把your_username换成你实际连不上那个用户,别只查root忘了应用账号 - 如果
plugin列显示caching_sha2_password,且你用的是 Navicat 12、PyMySQL mysqli - 特别注意
host字段:'user'@'localhost'、'user'@'127.0.0.1'、'user'@'%'是三个独立账号,Navicat 默认走127.0.0.1,但很多人只改了localhost就以为完事
ALTER USER 必须带密码,否则会锁死自己
这是最容易踩的坑:只写 IDENTIFIED WITH mysql_native_password 不加 BY,MySQL 会清空密码哈希,导致该账号彻底无法登录。
- 改本地连接:
ALTER USER 'app_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'real_password'; - 改远程连接:
ALTER USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'real_password'; - 改 127.0.0.1 连接(Navicat 默认):
ALTER USER 'app_user'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'real_password'; - 执行完必须跟一句:
FLUSH PRIVILEGES;,否则变更不生效,哪怕重启 mysqld 也没用 - 云数据库(如阿里云 RDS)不允许改配置文件,
ALTER USER是唯一可行路径
my.cnf 里设 default_authentication_plugin 为什么没用
这个配置项只影响「新建用户」,对已有用户完全无效。很多人改完 [mysqld] 段就重启,结果 root 和 app_user 还是 caching_sha2_password。
- 它只在初始化实例或创建新用户时起作用,升级后的存量用户不会被自动迁移
- systemd 环境下必须用
sudo systemctl restart mysqld,reload不触发插件重载 - Docker 启动时加
--default-authentication-plugin=mysql_native_password同样只管新用户,不能修复已存在的账号 - 某些云服务(RDS/CDB)直接屏蔽该配置,
SHOW VARIABLES LIKE 'default_authentication_plugin'仍显示caching_sha2_password
改完还是连不上?先关掉 Navicat 重开
GUI 工具缓存太深,比服务端问题更常导致“明明改了却连不上”。
- Navicat 会复用旧握手参数和连接池,不关软件、不删旧连接重建,它可能还在拿
caching_sha2_password协商 - 密码含
@、/、\会被 URL 解析吃掉,临时换纯字母数字密码快速验证 - Java 应用即使服务端已切回
mysql_native_password,若驱动是 5.1.x 或连接串缺allowPublicKeyRetrieval=true,仍会卡在 handshake 阶段 - PHP 用
mysqli扩展时,mysqlnd版本必须 ≥8.0.0,PHP 版本必须 ≥7.4,光调参数没用
真正要动的是用户记录里的 plugin 字段,不是配置文件,也不是连接字符串参数;而最容易被忽略的,是 host 匹配精度和客户端缓存——它们比插件切换本身更常让修复失败。











