MySQL远程连接不上,多数情况下原因出在授权、监听地址和防火墙这三处,按顺序排查,基本都能解决。
通过客户端从另一台机器连接服务器MySQL,报错五花八门,但根子其实就那么几个,下面带你一层一层扒开看。
服务器mysql远程连接失败?先查监听和授权
远程连接的本质是客户端通过TCP/IP访问3306端口,任何一个环节断掉,都会导致连接失败,先分清故障类型:是网络层不通,还是MySQL服务本身拒绝。
检查bind-address是不是只绑定了本机
MySQL安装后默认只监听127.0.0.1,这意味着只有本地能连,外部IP一律被拒绝,打开配置文件,常见路径为/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf。
找到[mysqld]段下的bind-address,如果写着0.0.1,把它改成0.0.0,或者直接注释掉这行,改完务必重启服务。
bind-address = 0.0.0.0
确认skip-networking没有开启
另一个常见坑是skip-networking,这个参数一旦等于true,MySQL会完全禁用TCP/IP,只允许Unix套接字连接,远程自然连不上,检查配置文件,有这一行就注释掉,或者改为skip-networking = off。
重启并验证3306端口在监听
配置改动后执行:
systemctl restart mysqld
或用service mysql restart,适用于不同发行版,然后看端口:
netstat -tlnp | grep 3306
能输出监听信息,说明服务层面没问题,若没有输出,检查启动日志,通常是/var/log/mysql/error.log。
mysql授权远程连接命令写错了,认证直接卡住
即使服务监听了所有IP,MySQL内部授权表不认你,照样连不上,这类问题最典型的表现是报错1130 - Host is not allowed to connect。
查清user表里的host字段
登录MySQL本地执行:
SELECT user, host FROM mysql.user;
如果你的账号host是localhost,那远程连接必然被拒,需要把host改为(代表任意IP)或指定客户端IP。
标准的mysql授权远程连接命令
以root账号为例,老版本MySQL(5.x)可以用:
GRANT ALL PRIVILEGES ON . TO 'root'@'%' IDENTIFIED BY '你的密码';
FLUSH PRIVILEGES;
MySQL 8.0及以上,GRANT不再支持创建用户时直接带IDENTIFIED BY,需要分两步:
CREATE USER 'root'@'%' IDENTIFIED BY '你的密码';
GRANT ALL PRIVILEGES ON . TO 'root'@'%';
FLUSH PRIVILEGES;
行业共识认为,直接开放root远程权限风险偏高,生产环境建议单独建一个远程账号,只授予所需权限。
按库授权比全面授权更稳妥
比如只允许某台应用服务器访问appdb库:
CREATE USER 'app_user'@'192.168.1.100' IDENTIFIED BY 'StrongPass';
GRANT ALL PRIVILEGES ON appdb. TO 'app_user'@'192.168.1.100';
FLUSH PRIVILEGES;
这样即使账号泄露,影响范围也只限于这一个库,同时把源IP固定到某个IP,比用安全性高出不少。
linux mysql远程连接设置里,防火墙和安全组缺一不可
检查完监听和授权后,如果还是连不上,问题大概率落在网络层,很多人把服务器内部防火墙折腾个遍,却忘了云平台的安全组规则,这种案例太多了。
内网防火墙放行3306端口
使用firewalld的CentOS或Rocky Linux:
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
使用iptables的系统,可以临时插入规则:
iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
service iptables save
注意顺序:INPUT链路默认策略是DROP时,放行规则必须放在拒绝规则之前。
云服务器安全组规则是第二个坑
简米云、酷番云、华为云的服务器,光改Linux内部防火墙没用,必须在云控制台找到“安全组”,添加入方向规则,协议选TCP,端口填3306,源地址按需设为0.0.0/0或特定IP段,忘记这一步,你试再多命令也白搭。
近年来相当一部分远程连接失败案例,就是安全组根本没放行。
检测端口通不通的快速方法
在本地电脑或另一台服务器上用telnet探测IP和端口:
telnet 服务器IP 3306
如果显示Connected,说明这段网络通的,如果卡住或超时,返回去查防火墙和安全组。
连接报错代码,帮你精准定位
不同的报错对应不同的故障点,记住几个常见报错能省大量排查时间。
1130 – Host is not allowed to connect to this MySQL server
不用怀疑,就是授权问题,user表里没有匹配你当前连接来源IP的条目,按前面方法执行授权并FLUSH PRIVILEGES,再重试。
2003 – Can’t connect to MySQL server on
这个报错说明网络层面就没找到MySQL服务,排查顺序依次是:
- 3306端口是否在监听
- 内网防火墙是否阻断
- 云安全组是否放行
- 服务器公网IP是否可达
1045 – Access denied for user
表示找到了服务,但账号或密码验证没过,先确认密码有没有输对,如果MySQL 8.0用了caching_sha2_password插件,而客户端工具较旧,也可能认证失败,可以用下面命令改回mysql_native_password:
ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY '密码';
FLUSH PRIVILEGES;
Q&A:mysql远程连接不上还有哪些隐蔽原因
问题1:我已经改了bind-address和授权,为什么还是连不上?
大概率卡在云安全组或SELinux,先用telnet 公网IP 3306验证端口通不通;再检查本机防火墙,如果系统开启了SELinux,执行getenforce查看状态,临时关闭用setenforce 0。
问题2:MySQL 8.0按教程授权后,客户端一直报密码错误?
如上所述,8.0默认的认证插件是caching_sha2_password,老版本Navicat或PHP mysqli不一定支持,用ALTER USER把插件改为mysql_native_password,再刷新权限,通常就解决了。
问题3:只想让某个固定IP远程连MySQL,怎么设置更安全?
把授权语句里的host从改为具体IP,例如'203.0.113.5',同时清掉mysql.user中多余的'user'@'%'记录,避免权限重叠,再通过防火墙或安全组把3306端口的源IP限定为该地址。
MySQL远程连接不上的坑看似五花八门,按“监听地址 → 用户授权 → 防火墙/安全组”这个顺序排查,每一层都有明确验证命令,基本几分钟就能定位问题,遇到报错先看代码,再对照上面的步骤逐项检查,你会发现把远程连上MySQL并没有想象中那么难。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/749886.html





