连不上mysql的根因常是客户端不支持caching_sha2_password认证插件,需依次确认插件类型、用户host匹配、bind-address配置及防火墙放行;'root'@'localhost'、'root'@'127.0.0.1'、'root'@'%'为三条独立记录,必须按实际连接host逐一配置。

连不上不是密码错了,是客户端不认识 caching_sha2_password 插件——必须先确认插件类型、再匹配用户 host、最后检查网络层是否放行。
查清楚当前用户用的是哪个认证插件
用能连上的账号(比如本地 mysql -u root -p)登录后执行:
SELECT user, host, plugin FROM mysql.user WHERE user = 'your_username';
重点看 plugin 列:如果是 caching_sha2_password,而你用的是 Navicat 12/13、PyMySQL mysqli 7.2–7.4、MySql.Data
-
'root'@'localhost'、'root'@'127.0.0.1'、'root'@'%'是三条完全独立的记录,不能只查localhost就以为全搞定了 - Navicat 默认走 TCP 连接,实际连接 host 是
127.0.0.1或公网 IP,不是localhost - 如果返回空,说明该用户根本不存在,得先
CREATE USER,不能直接ALTER USER
改认证插件必须带密码、匹配 host、立即刷新
ALTER USER 这条命令漏掉任意一个条件都会锁死账号:
- 不能只写
IDENTIFIED WITH mysql_native_password,必须显式加BY 'real_password'——否则密码哈希被清空,账号彻底失联 - host 必须和你远程连接时用的一致:连的是
192.168.1.100,就得改'user'@'192.168.1.100';连的是%,就改'user'@'%' - 执行完必须立刻跟
FLUSH PRIVILEGES;,部分 Docker 和云 RDS 环境不执行这句,变更根本不生效 - 如果报
ERROR 1396 (HY000),说明该用户不存在,得先CREATE USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx';
bind-address=0.0.0.0 不等于远程可连
即使插件改对了、用户建好了,服务端本身没监听外部地址,客户端连都连不上:
- 检查 MySQL 是否监听
0.0.0.0:3306:sudo netstat -plnt | grep :3306,若只显示127.0.0.1:3306,说明只限本地 - 编辑
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf,找到bind-address行,改为bind-address = 0.0.0.0或直接注释掉 - 改完必须重启服务:
sudo systemctl restart mysqld(或mysql,取决于系统服务名) - 防火墙必须放行 3306:
sudo ufw allow 3306(Ubuntu)或检查云服务器安全组规则
客户端缓存和特殊字符常被忽略
改完服务端配置,仍连不上?大概率卡在这几个细节上:
- Navicat / DataGrip 会缓存旧连接配置,关掉重开,或删掉该连接重新建
- 你改了
'user'@'localhost',但 Navicat 实际连的是127.0.0.1——这是两个不同 host,得单独改'user'@'127.0.0.1' - 密码含
@、/、\等字符时,Navicat 或 JDBC URL 解析可能出错,换一个纯字母数字密码快速验证 - 某些 PHP 配置(如
mysqli.default_socket)会强制走 socket 连接,绕过 TCP,导致 host 匹配失效
真正容易被忽略的是:插件改了,用户建了,bind-address 改了,防火墙也开了——但你连的是 127.0.0.1,而只改了 'user'@'%',没碰 'user'@'127.0.0.1'。MySQL 认证是严格按 User+Host 二元组匹配的,少一条,就少一个入口。











