mysql远程连接失败主因是host字段限制与防火墙双重拦截,需同步修改用户host权限、配置bind-address=0.0.0.0、开放3306端口及云安全组规则,并执行flush privileges。

MySQL 默认拒绝所有远程连接,不是密码错、也不是端口关,而是 host 字段锁死了来源地址,再加防火墙拦截,双重拦停。必须同时改权限、放端口,缺一不可。
查清当前用户的 host 是什么
登录 MySQL 后第一件事不是授权,是确认目标用户实际绑定的 host 值:
- 执行
SELECT User, Host FROM mysql.user;,重点看你要用的那个用户名对应的Host列值 - 如果显示
localhost或127.0.0.1,那它根本不会接受远程 IP 的连接请求 -
'root'@'localhost'和'root'@'%'是两个完全独立的账号,不能混为一谈 - 别直接
UPDATE mysql.user SET Host='%' WHERE User='root';—— 这会覆盖已有记录,可能让本地 root 也登不上
用 CREATE USER + GRANT 显式授权指定 IP
比 UPDATE 更安全、更可控的方式是新建专用用户,并精确控制其 host:
- 允许单个固定 IP:
CREATE USER 'app'@'192.168.1.100' IDENTIFIED BY 'strong_pass'; - 允许某内网段:
CREATE USER 'app'@'192.168.1.%' IDENTIFIED BY 'strong_pass';(注意是%,不是*) - 赋权后必须跟
FLUSH PRIVILEGES;,否则权限不加载到运行时 - 避免用
GRANT ... TO 'app'@'%';不带CREATE USER—— 如果该用户已存在但host是localhost,这条语句不会创建新记录,也不会报错,容易误以为成功
bind-address=0.0.0.0 不等于“开了远程”
即使 host 权限全开,MySQL 服务本身不监听外部地址,照样连不上:
- 检查配置文件(
/etc/mysql/mysql.conf.d/mysqld.cnf或/etc/my.cnf),确认[mysqld]段下有bind-address = 0.0.0.0 - 不要写成
bind-address = localhost或留空,也不要删掉这行 —— 缺失时 MySQL 可能回退到默认127.0.0.1 - 确认没有
skip-networking这行,有就注释掉 - 改完必须重启服务:
sudo systemctl restart mysql,然后用netstat -tlnp | grep :3306验证是否监听0.0.0.0:3306
防火墙和云安全组是最后一道卡点
ERROR 2003 “Can't connect to MySQL server” 多半出在这层,而不是数据库内部:
- 本地防火墙:Ubuntu/Debian 用
sudo ufw allow 3306;CentOS/RHEL 用sudo firewall-cmd --permanent --add-port=3306/tcp && sudo firewall-cmd --reload - 云服务器(阿里云、腾讯云等)必须单独配安全组规则,仅开系统防火墙不够 —— 安全组是云平台网络层的硬隔离
- 测试时优先用命令行:
mysql -h 服务器IP -u app -p,别一上来就用 Navicat,避免图形工具自带缓存或 DNS 解析干扰判断 - 如果连通但报
ERROR 1130,说明请求已抵达 MySQL,问题纯在权限侧;如果是超时或拒绝连接,一定是网络层(防火墙/安全组/绑定地址)没通
最常被跳过的其实是 FLUSH PRIVILEGES; 和安全组配置,尤其是后者——很多人只记得开服务器防火墙,却忘了云厂商还有独立的安全组面板,而且默认全拒。











