MySQL 8.0默认认证插件改为caching_sha2_password,导致老客户端连接失败;解决方法是用ALTER USER将用户认证插件切回mysql_native_password,并确保host匹配准确,必要时双写localhost与127.0.0.1。
MySQL 8.0 默认认证插件改成了 caching_sha2_password,老客户端连不上
mysql 8.0+ 默认用 caching_sha2_password 替代了旧的 mysql_native_password,但很多老工具(比如 mysql workbench 6.x、navicat 旧版、php 7.2 以下的 mysqli 扩展)不支持它,直接报错:client does not support authentication protocol requested by server。
这不是密码错了,是握手协议不兼容。最直接的解法不是升级所有客户端,而是让用户账号退回到兼容模式:
- 登录 MySQL(用 root 或有
CREATE USER/ALTER USER权限的账号) - 执行:
ALTER USER 'your_user'@'host' IDENTIFIED WITH mysql_native_password BY 'your_password';
- 立刻生效,不用重启 MySQL
- 如果要批量改所有本地用户,可查
SELECT user, host, plugin FROM mysql.user;确认范围
ALTER USER 报错 ERROR 1396 (HY000): Operation ALTER USER failed
常见于用户不存在,或 host 匹配不精确——MySQL 认为 'user'@'localhost' 和 'user'@'127.0.0.1' 是两个不同账号。
先确认账号真实存在:
- 运行
SELECT user, host FROM mysql.user WHERE user = 'your_user'; - 注意输出里的
host字段值,可能是%、localhost、127.0.0.1,必须完全一致 - 如果只记得用户名,不确定 host,可用通配:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';
- 如果用户根本不存在,得先
CREATE USER,再GRANT
改完还是连不上?检查连接时实际用的 host
你以为连的是 localhost,但客户端可能悄悄用了 127.0.0.1(尤其 PHP 的 mysqli_connect('127.0.0.1', ...)),而这两个在 MySQL 权限系统里是分开的。
安全做法是双写:
ALTER USER 'your_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
ALTER USER 'your_user'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'your_password';
- 或者一步到位允许任意 host:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';
(生产环境慎用)
改完别忘了 FLUSH PRIVILEGES; —— 虽然 ALTER USER 通常自动刷新,但某些 MySQL 版本或配置下仍需手动刷。
要不要全局降级默认插件?
可以,但不推荐。改全局会影响所有新建用户,包括未来可能用到新协议的工具或服务。
如果真要改,在 my.cnf 的 [mysqld] 段加一行:
default_authentication_plugin=mysql_native_password
然后重启 MySQL。但注意:
- 已有用户不受影响,仍需单独
ALTER USER - 新创建的用户会用
mysql_native_password,但你可能忘了这事,后续换新客户端时又卡住 - SHA2 加密本身更安全,降级等于主动放弃一层防护
真正该花时间的地方,其实是把关键客户端升级到支持 caching_sha2_password 的版本——比如 PHP 7.4+、MySQL Workbench 8.0+。临时切回老插件只是过渡,不是终点。



















