同一台 MySQL,使用 localhost 可以登录,换成 IP 却失败,并不一定是密码或授权问题。应先看完整错误,再判断连接失败发生在哪一层。

下面的命令以 MySQL 命令行客户端为例;JDBC、图形客户端和不同操作系统的默认连接方式可能不同。

1. 对照本地 socket 和 TCP

在 Unix 系统上,MySQL 命令行客户端通常对 localhost 使用 Unix socket;指定 IP 或显式选择 TCP 时才走 TCP。即使本地登录成功,也不能证明数据库正在接受网络连接。MySQL 8.0 连接方式

可在自己管理的机器上,使用已有账号分别测试:

mysql --host=localhost --user=app_user --password
mysql --protocol=TCP --host=127.0.0.1 --port=3306 --user=app_user --password

账号和端口应换成实际值;—password 后不填写密码,让客户端交互提示,避免密码进入命令历史。若实际配置要求 TLS,应同时使用正确的 TLS 参数。

第一条成功、第二条失败时,重点查看 TCP 监听和相应连接认证,不能直接跳到“开放远程 root”。

2. 先分清错误类型

  • 连接拒绝:检查目标地址、端口、进程监听和转发关系,也可能是网络设备主动拒绝。
  • 连接超时:检查路由、防火墙、安全组与目标可达性,不能仅凭超时确定某一处配置。
  • Access denied:请求已经到达某个 MySQL 服务,继续核对账号、来源、密码、认证方式及安全要求。
  • Unknown database 或操作被拒绝:分别检查库名及库表权限,不再按端口不通处理。

如果用了容器、SSH 隧道或代理,还要确认连接的确实是预期实例。

3. 检查服务监听,而不是直接关闭防火墙

有权限的管理员可通过已有本地连接查看:

SHOW VARIABLES LIKE 'port';
SHOW VARIABLES LIKE 'bind_address';
SHOW VARIABLES LIKE 'skip_networking';

bind_address 影响 TCP 监听地址;只监听回环地址时,不能直接接受其他机器发来的连接。skip_networking 也会影响 TCP 支持。实际端口还应和容器映射、代理上游及主机监听状态对照。MySQL bind_address 说明

确有远程访问需求时,优先使用受控内网、VPN 或隧道,并仅放行必要来源。修改监听配置可能涉及服务重启,应有备份和维护窗口;不要为了试一下就将数据库暴露到公网。

4. 连接到了服务,再检查匹配账号

MySQL 的账号同时包含用户名和 Host。相同用户名从不同来源连接,可能匹配不同的账号记录;Host 表示服务器看到的客户端来源,不是数据库服务器自己的地址。

成功连接后可查看:

SELECT USER(), CURRENT_USER();
SHOW GRANTS;

CURRENT_USER() 有助于确认实际匹配的账号,SHOW GRANTS 查看相应授权。若连接失败,则由管理员在授权范围内检查目标账号,不要直接修改系统授权表。MySQL 连接验证

需要补权限时,应给已经按安全流程创建好的专用账号授予必要库表权限。例如下面只是管理员授权示意,地址使用文档保留值,不能原样套到生产:

GRANT SELECT ON app_db.article
TO 'app_reader'@'192.0.2.25';

这是只读单表权限,不是所有库表和任意来源。MySQL 8.0 应分别创建账号和授权,不能照搬用 GRANT 附带创建账号的旧语法。

5. 不必把刷新权限和重启当成固定收尾

正常使用 CREATE USER、ALTER USER、GRANT 等账号管理语句时,服务器会相应更新权限信息,不需要再机械执行 FLUSH PRIVILEGES;已有会话的具体生效规则则与变更类型有关。MySQL 权限变更生效规则

修复后从实际应用所在机器重新连接,并验证它能完成所需操作、不能访问无关数据。能登录只是连接检查通过,不等于权限边界也已经正确。