根本原因是mysql.user表中缺少匹配客户端ip的'user'@'host'记录,mysql未进入密码校验阶段;需创建对应用户、授权并刷新权限,同时检查plugin、bind-address及防火墙。

不是密码错了,而是 MySQL 根本没走到校验密码那步——mysql.user 表里没有匹配你这次连接所用的 'user'@'host' 这条记录。
为什么 mysql -h 192.168.1.100 -u dev -p 连不上,但本地能连?
MySQL 的 host 字段是精确字符串匹配,不是模糊通配。你远程连接时,客户端实际发的是 'dev'@'192.168.1.100'(或 'dev'@'172.17.0.1',Docker 场景下常见),而表里只有 'dev'@'localhost',这两条完全不等价:
-
'dev'@'localhost'走 Unix socket,只响应不带-h的本地连接 -
'dev'@'127.0.0.1'走 TCP,必须显式指定-h 127.0.0.1 -
'dev'@'%'匹配绝大多数 IPv4,但不匹配localhost或::1
为什么直接 UPDATE mysql.user SET Host = '%' 常常无效?
手改表看似快,实则埋雷最多:
将 WCAG 2 AA 无障碍标准应用于设计系统、UI 组件和网页——通过可运行的验证器进行对比度计算,采用设计 token 模式使颜色天生可访问,设定排版和焦点状态规则,并提供语义检查清单。适用于构建或审查 UI。
- 改的是某一条记录(比如把
'dev'@'192.168.1.100'改成'dev'@'%'),但原'dev'@'localhost'还在,不影响本地连接;可如果你改的是'root'@'localhost',反而可能让mysql -u root失效 - MySQL 8.0+ 对
'%'的匹配有隐含限制:跳过localhost、跳过::1、跳过 DNS 解析后的域名(如client.example.com) - 改完不执行
FLUSH PRIVILEGES,新Host值根本不会加载,SHOW GRANTS FOR 'dev'@'%'会返回空
旧客户端连不上 MySQL 8.0+?大概率是插件问题
MySQL 8.0+ 默认使用 caching_sha2_password 插件,但很多旧工具(如 PHP 7.4 + mysqli、Navicat 12、某些 JDBC 驱动)不支持它:
- 现象:用户名密码完全正确,但卡在连接阶段,错误信息仍是
Access denied for user - 验证方式:查
SELECT user, host, plugin FROM mysql.user,看目标用户是否用了caching_sha2_password - 临时解法:
ALTER USER 'dev'@'%' IDENTIFIED WITH mysql_native_password BY 'your_pwd'; FLUSH PRIVILEGES;
防火墙和 bind-address 是硬性门槛
即使权限全对,网络层不通照样连不上:
-
bind-address默认是127.0.0.1,只监听本地;需改成0.0.0.0或注释掉该行,然后重启 MySQL 服务 - Linux 上检查
ufw status或iptables -L,确认3306/tcp开放;云服务器还要检查安全组规则 - Docker 容器内连宿主机 MySQL,源 IP 往往是网桥地址(如
172.17.0.1),不是你本机 IP —— 所以授权时得用那个地址,不是%
真正麻烦的点不在命令怎么写,而在你看到的错误信息里藏着三重坐标:user、host、plugin。漏掉任何一个,都只是“看起来像连上了”,实际根本没匹配到那条权限记录。










