ALTER USER后仍连接失败的三大主因是:未执行FLUSH PRIVILEGES、host不匹配(如改localhost却连IP)、客户端缓存旧握手逻辑;需查SELECT user,host,plugin FROM mysql.user确认插件并人工重置密码,且客户端驱动必须升级适配。

直接改用户认证方式,别碰default_authentication_plugin配置项——它对已有用户完全无效。
为什么ALTER USER后还是连不上
执行了ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password BY 'pwd'却仍报SQLSTATE[HY000] [2054]或ERROR 1251,常见原因有三个:
- 漏掉
FLUSH PRIVILEGES:权限变更不会自动生效,必须手动刷新 -
host不匹配:比如应用连的是'user'@'192.168.1.100',但你只改了'user'@'localhost';查当前连接来源用SELECT user, host FROM mysql.user WHERE user = 'user'; - 客户端缓存旧握手逻辑:老版 Navicat、DBeaver 或某些 Java 连接池会复用连接上下文,重启客户端比重启 MySQL 更有效
如何确认并批量修复所有非mysql_native_password用户
先查哪些用户还在用新插件:
SELECT user, host, plugin FROM mysql.user WHERE plugin != 'mysql_native_password';
结果里看到caching_sha2_password就说明要处理。注意:mysql.user在 8.0 是视图,不能UPDATE,只能ALTER USER。批量生成语句可这样写:
SELECT CONCAT("ALTER USER '", user, "'@'", host, "' IDENTIFIED WITH mysql_native_password BY '", authentication_string, "';") FROM mysql.user WHERE plugin = 'caching_sha2_password';
⚠️但authentication_string是哈希值,不能直接当明文密码用;实际操作中需人工提供真实密码,或先用强密码重置再改插件。
Java/PHP/Python 客户端连不上,光改用户还不够
即使服务端已切回mysql_native_password,驱动版本或参数不对照样失败:
- Java:用
mysql-connector-java≥ 8.0.12,连接串加?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC;5.1.x 驱动根本不支持caching_sha2_password,升级是唯一解 - PHP:
mysqlnd≥ 8.0.0(对应 PHP ≥ 7.4),旧版 PHP 5.x 或 7.0–7.3 的mysqli扩展无法协商新协议 - Python:弃用
MySQLdb(已停止维护),改用pymysql或mysql-connector-python≥ 8.0.12
驱动不升级,只调服务端参数,会在长连接复用、连接池回收等场景偶发握手失败——这点最容易被忽略。


















