mysql 8.0默认认证插件为caching_sha2_password,旧客户端(如navicat 15、php 7.4 mysqlnd)不支持,导致1251错误;需执行alter user 'root'@'%' identified with mysql_native_password by 'pwd';并flush privileges。

直接改 caching_sha2_password 插件不是必须的,但如果你用的是旧版 Navicat、SQLyog 或某些 PHP/Python 客户端,ALTER USER ... IDENTIFIED WITH mysql_native_password 是最快速有效的解法。
为什么会出现 1251 错误
MySQL 8.0 默认把 root 用户的认证插件设为 caching_sha2_password,而很多客户端(比如 Navicat 15 及更早版本、PHP 7.4 的 mysqlnd 默认配置、某些 Python PyMySQL 旧版本)不支持这个插件。报错时完整信息通常是:
1251 - Client does not support authentication protocol requested by server; consider upgrading MySQL client
这不是密码错了,也不是网络不通,是握手阶段就卡在认证协议不匹配上。
怎么确认当前用户用的是哪个插件
先连进 MySQL(哪怕只能用命令行)执行:
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';
如果结果里 plugin 列显示 caching_sha2_password,那基本就是它了。注意检查 host 值 —— 你远程连接用的是 'root'@'%' 还是 'root'@'localhost'?两者要分别处理。
- 如果是
'root'@'localhost',命令中必须写全'root'@'localhost',不能只写'root' - 如果是远程连接(比如 Navicat 填的是服务器 IP),大概率对应的是
'root'@'%',得改这个 - 改完后记得执行
FLUSH PRIVILEGES;,否则不生效
如何安全地切换回 mysql_native_password
执行这条语句即可(把 your_password 换成实际密码):
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';
常见错误点:
- 漏掉
@'%'或写成@'localhost'导致远程仍连不上 - 没加
WITH mysql_native_password,只写了IDENTIFIED BY,结果插件没变,密码倒是重置了 - 容器环境里,MySQL 启动后可能需要等几秒再连,否则报
Access denied(其实是服务还没 ready) - Docker 中如果用了
-e MYSQL_ROOT_PASSWORD=xxx启动,首次连接要用这个密码,之后才能执行ALTER USER
长期来看,该不该一直用 mysql_native_password
能用,但不推荐长期依赖。因为 caching_sha2_password 真的安全性更高:SHA-256 + 盐值 + 内存缓存,且强制要求 SSL 传输密钥时更健壮。真正该做的,是升级客户端或调整连接参数:
- Navicat 16+ 已原生支持
caching_sha2_password,建议升 - PHP 项目里,
mysqli或PDO连接时加上options => [PDO::MYSQL_ATTR_SSL_MODE => PDO::MYSQL_ATTR_SSL_MODE_REQUIRED]可启用兼容模式 - Docker 启动时加参数
--default-authentication-plugin=mysql_native_password能让新用户默认用老插件,但已存在的用户不受影响
最常被忽略的一点:改完插件后,别忘了检查用户权限是否还覆盖目标 host —— 'root'@'localhost' 和 'root'@'%' 是两个独立账户,权限要各自赋。











