
旧客户端连不上 MySQL 8.0+:mysql_native_password 被禁用
MySQL 8.0 默认改用 caching_sha2_password 插件,老客户端(比如 MySQL 5.7 客户端、某些 Python 2 的 MySQLdb、旧版 Navicat、PHP 7.2 以下的 mysqli)不支持这个新认证方式,会报错:Authentication plugin 'caching_sha2_password' cannot be loaded 或直接拒绝连接。
这不是密码错了,是握手阶段就卡在认证插件不兼容。最直接的解法不是升级所有客户端,而是让用户账户退回到 mysql_native_password 认证。
- 登录 MySQL(用 root 或有
CREATE USER/ALTER USER权限的账号) - 执行:
ALTER USER 'your_user'@'host' IDENTIFIED WITH mysql_native_password BY 'your_password';
- 立即生效,无需重启 MySQL
- 如果用户不存在,先用
CREATE USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd';
全局默认认证插件能改吗?default_authentication_plugin
可以,但只影响后续新建用户的默认认证方式,不影响已有用户。修改后,新 CREATE USER 不带 IDENTIFIED WITH 就会用这个插件。
在 my.cnf 的 [mysqld] 段加一行:
default_authentication_plugin=mysql_native_password
- 改完必须重启 MySQL 才生效
- 仅对新用户有效;已存在的用户仍保持原认证插件,得单独
ALTER USER - MySQL 8.0.4+ 允许设为
mysql_native_password,但 8.0.25+ 官方已明确不推荐,未来版本可能移除支持 - 如果同时启用了
sha256_password插件但没加载,启动会报错,需确认插件状态:SHOW PLUGINS;
为什么不能只改密码?SET PASSWORD 不等于换认证插件
SET PASSWORD FOR 'u'@'h' = 'xxx'; 只改密码哈希值,不碰认证插件。用户还是用原来的插件验证——如果原来是 caching_sha2_password,改完密码照样连不上老客户端。
- 必须显式指定
IDENTIFIED WITH才能切换插件 -
ALTER USER ... IDENTIFIED BY 'xxx'在 8.0+ 默认沿用当前插件,不会自动降级 - 查当前用户用的什么插件:
SELECT user, host, plugin FROM mysql.user WHERE user = 'your_user'; - 插件列显示
caching_sha2_password就得手动切,别指望重设密码能解决
PHP 连接失败还可能是 mysqlnd 版本太低
即使用户认证插件改对了,PHP 如果用的是老旧 mysqlnd 驱动(如 PHP 7.1 自带的),它压根不实现 caching_sha2_password 握手流程,也不支持服务端要求的 RSA 密钥交换——这时候哪怕你把用户切回 mysql_native_password,它也可能因驱动 bug 报 SSL connection error 或静默失败。
- 检查 PHP 的
mysqlnd版本:php -i | grep mysqlnd,低于5.0.12基本都有问题 - 升级 PHP 到 7.4+ 或 8.x 是最稳的方案;若无法升级,确保
mysqli.default_socket指向正确 socket,且禁用 SSL:$mysqli->options(MYSQLI_OPT_SSL_MODE, MYSQLI_SSL_DISABLED); - Docker 环境常见坑:Alpine 镜像里 php-mysql 扩展可能用的是系统自带旧版
mysqlnd,得换php:apache或手动编译
认证插件切换只是表层动作,底层驱动兼容性才是藏得最深的断点。别只盯着 SQL 命令跑通,得一层层验到客户端实际发出去的握手包长什么样。











