优先执行ALTER USER 'username'@'host' IDENTIFIED WITH mysql_native_password BY 'your_password'; 并FLUSH PRIVILEGES;,或升级客户端支持caching_sha2_password,全局配置default_authentication_plugin仅影响新用户创建。
MySQL 8.0 默认插件导致客户端连接失败怎么办
mysql 8.0+ 默认启用 caching_sha2_password 插件,但老版本 mysql 客户端(如 mysql 5.7 cli、某些 python 2.7 的 mysqlclient、旧版 php mysqli 扩展)不支持该插件,直接报错:authentication plugin 'caching_sha2_password' cannot be loaded 或 client does not support authentication protocol requested by server。
这不是密码错了,是认证协议不兼容。解决思路只有两个:降级用户插件,或升级客户端支持能力。优先推荐前者,尤其在测试/运维环境快速恢复连接时。
- 执行
ALTER USER 'username'@'host' IDENTIFIED WITH mysql_native_password BY 'your_password';切换认证方式 - 必须刷新权限:
FLUSH PRIVILEGES; - 注意:该操作仅影响指定用户,不影响其他用户或全局配置
- 如果用 root 操作,确保 host 是实际连接来源(比如
'root'@'localhost'而非'root'@'%')
my.cnf 配置全局禁用 caching\_sha2\_password 是否安全
可以在 MySQL 启动配置中强制所有新用户使用旧插件:default_authentication_plugin=mysql_native_password。但这只是“默认”,不影响已有用户,也不等于禁用 caching_sha2_password 插件本身——它依然存在、可被显式指定。
真正风险在于:这个配置会让后续 CREATE USER 不带 IDENTIFIED WITH 时自动用 mysql_native_password,削弱默认安全性。MySQL 8.0 引入 caching_sha2_password 就是为了避免明文传输和重放攻击,它支持 RSA 密钥交换(当客户端不支持 SHA2 时可回退)。
- 开发环境可用,生产环境慎用
- 修改后需重启 mysqld 才生效(
systemctl restart mysqld) - 检查是否生效:
SELECT plugin FROM mysql.user WHERE User='someuser'; - 该配置对已存在的
caching_sha2_password用户无影响
Python 连接报错 “caching\_sha2\_password is not supported” 怎么修
常见于使用 PyMySQL 旧版本(mysqlclient(基于 MySQL C API,需底层支持)。PyMySQL 从 0.9.3 开始原生支持 caching_sha2_password;mysqlclient 则依赖编译时链接的 MySQL client library 版本(≥ 8.0.4)。
最直接的办法不是升级驱动,而是让连接显式声明支持——前提是驱动版本够新:
- PyMySQL:加参数
auth_plugin='mysql_native_password'(绕过问题),或升级到 ≥ 1.0 并确保服务端允许 RSA 加密(见下一条) - mysqlclient:升级到 ≥ 2.0.0,并确认
mysql_config --version输出 ≥ 8.0.4 - 若坚持用
caching_sha2_password,服务端需开启 RSA 支持:sudo cp /var/lib/mysql/private_key.pem /etc/mysql/conf.d/并在 my.cnf 加sha256_password_private_key_path=/etc/mysql/conf.d/private_key.pem(极少必要)
PHP mysqli_connect() 连不上 caching\_sha2\_password 用户
PHP 7.4+ 原生支持 caching_sha2_password,但前提是编译时链接了 MySQL 8.0+ client library。很多 Docker 镜像或系统包仍用 5.7 client,就会失败。
不用重装 PHP,改连接方式更稳妥:
- 用
mysqli_init()+options(MYSQLI_OPT_CONNECT_TIMEOUT, ...)不解决问题,关键在底层协议支持 - 临时方案:在 DSN 中强制指定插件:
mysqli://user:pass@host/db?auth_plugin=mysql_native_password(部分封装库支持,原生 mysqli 不认) - 真正有效的是改用户认证方式(第一小节的方法),或升级系统 mysql-client 包(Ubuntu/Debian:安装
libmysqlclient21;CentOS/RHEL:启用 mysql80-community repo) - 验证方法:
php -r "var_dump(mysqli_get_client_info());"看输出是否含 8.0+
插件切换是即时生效的,但客户端缓存的 DNS 或连接池可能保留旧状态,建议连上后执行 SELECT CURRENT_USER(), @@session.plugin; 确认当前会话实际使用的插件。










