MySQL远程连接失败的首要原因是bind-address=127.0.0.1导致服务未监听外部网络,即使用户权限、密码、防火墙均正确也必然失败;必须改为bind-address=0.0.0.0并重启服务,再配合用户授权、防火墙及安全组开放3306端口。

改完 bind-address = 127.0.0.1 后远程授权账号立刻失效,不是权限没生效,是 MySQL 根本不接收远程 TCP 请求——连接连三次握手都进不来,压根没走到认证那步。
MySQL 没监听外部端口,授权再全也没用
只要 bind-address = 127.0.0.1,MySQL 进程只监听本地回环地址。哪怕你执行了 GRANT ALL ON *.* TO 'user'@'%' 并 FLUSH PRIVILEGES,远程客户端发来的 SYN 包在操作系统网络栈就被丢弃,MySQL 进程完全无感知。
验证方式很简单:
- 在服务器上跑
ss -tlnp | grep :3306,如果只看到127.0.0.1:3306,没出现*:3306或0.0.0.0:3306,说明服务没对外暴露 - 从另一台机器执行
telnet your-server-ip 3306,若超时或直接拒绝,基本可断定是绑定地址问题,而非账号权限
MySQL 8.0+ 的 mysqlx-bind-address 也得同步改
很多教程只提 bind-address,但 MySQL 8.0 默认启用 X Protocol(用于 MySQL Shell、Router 等),它由独立参数 mysqlx-bind-address 控制。如果只改了 bind-address 却漏掉这一项,X 协议仍绑在 127.0.0.1,某些客户端(如新版 MySQL Workbench 启用 X DevAPI)会静默失败。
检查并修改配置:
- 搜这两行:
bind-address = 127.0.0.1和mysqlx-bind-address = 127.0.0.1 - 都改为
bind-address = 0.0.0.0和mysqlx-bind-address = 0.0.0.0,或删掉整行(部分版本默认即为 0.0.0.0) - 改完必须重启服务:
sudo systemctl restart mysql,否则配置不加载
用户 host 匹配和认证插件要分开看
即使端口监听正常,'user'@'%' 也不等于“所有 IP 都能连”。MySQL 认证匹配的是 user+host+password 三元组,且 MySQL 8.0+ 默认用 caching_sha2_password 插件。老客户端(如某些 PHP 7.4 扩展、旧版 Navicat)不支持该插件,会卡在握手阶段,报错类似 Authentication plugin 'caching_sha2_password' cannot be loaded。
临时兼容方案(非生产推荐):
- 建用户时指定插件:
CREATE USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd123'; - 或对已有用户重置:
ALTER USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd123'; -
FLUSH PRIVILEGES仍需执行,但注意:仅刷新权限表,不解决监听或插件不兼容问题
真正卡住远程连接的,往往不是 GRANT 命令写得对不对,而是 bind-address 和 mysqlx-bind-address 这两个配置文件里的值是否被实际加载、是否被其他同名参数覆盖、以及重启有没有真正生效——这些细节比 SQL 语句本身更容易被忽略。


















