连不上是客户端不支持caching_sha2_password插件,需用mysql命令行查mysql.user表确认plugin字段,再用alter user切换为mysql_native_password并flush privileges。

连不上不是密码错、也不是网络不通,是客户端压根不认识 caching_sha2_password 这个插件——它卡在 TCP 握手后的认证阶段,报错类似 ERROR 2059 或 Authentication plugin 'caching_sha2_password' cannot be loaded。
怎么确认真是 caching_sha2_password 惹的祸
用能连上的方式(比如 mysql -u root -p 本地 socket)登录 MySQL 命令行,执行:
SELECT user, host, plugin FROM mysql.user WHERE user = 'your_user';
重点看 plugin 列。如果显示 caching_sha2_password,且你用的是 Navicat 15 以下、PyMySQL、旧版 JDBC 驱动或 PHP mysqli,基本就是它了。
-
'root'@'localhost'和'root'@'127.0.0.1'是两个独立用户,Navicat 默认走后者,很多人只改了前者却连不上 - 云数据库(如阿里云 RDS)通常禁止查
mysql.user,但ALTER USER一般仍可用 - 错误里出现
Authentication requires secure connection,大概率是主从复制场景,不是用户连接问题
ALTER USER 切认证插件必须带密码
语法必须完整,漏掉 BY 'pwd' 会清空密码,导致账户锁死:
安全的随机密码生成器。支持自定义长度、字符类型(大写/小写字母、数字、特殊符号),排除相似字符,批量生成。纯 Python 标准库,无需 API 密钥。
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'MyPass123!';
常见操作组合:
- 本地 socket 连接:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'xxx'; - 本机 TCP(Navicat 默认):
ALTER USER 'root'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'xxx'; - 远程连接:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx'; - 改完立刻执行:
FLUSH PRIVILEGES;,否则不生效 - 如果只是换插件、不改密码,可省略
BY子句:ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password;
JDBC / PyMySQL / Navicat 连不上?服务端改完客户端也得动
服务端切回 mysql_native_password 只解决一半问题,客户端行为必须同步调整:
- Navicat:必须关闭重开软件,或删掉旧连接重建——它缓存握手参数,不刷新就重试旧流程
- JDBC:驱动必须 ≥ 8.0.16,URL 加参数:
?allowPublicKeyRetrieval=true&useSSL=false;5.1.x驱动硬加参数也无效 - PyMySQL:≤ 0.9.x 不支持
caching_sha2_password,换用 ≥ 1.0.2 并显式指定auth_plugin='caching_sha2_password' - 命令行
mysql客户端:5.7 及更早版本无法连接,要么升级客户端,要么启动时加--default-auth=mysql_native_password
my.cnf 里设 default_authentication_plugin 没用?没错
default_authentication_plugin = mysql_native_password 只影响「之后新建的用户」,对已存在的 root、repl 等用户完全无效。重启 MySQL、FLUSH PRIVILEGES 都不会让老用户自动切换插件。
- Docker 启动加
--default-authentication-plugin=mysql_native_password同样不修复存量用户 - 云服务(RDS/CDB)通常禁写配置文件,这条路根本走不通
- 有人改完配置就以为搞定,结果还是连不上——因为
mysql.user表里的plugin字段没变
真正麻烦的不是哪一行 SQL,而是整个链路中任意一环卡在旧协议上:比如 Spring Boot 应用用了新版驱动,但中间件(如 ShardingSphere)用的还是旧 JDBC 层,照样失败。










