“Connection refused”本质是TCP连接未触达MySQL进程,首要排查服务是否运行、端口是否监听、防火墙是否放行;90%以上源于mysqld未启动、bind-address=127.0.0.1或3306端口被拦截,应按“服务状态→监听配置→网络通路”顺序逐层验证。

“Connection refused”不是权限或密码问题,而是TCP连接根本没触达MySQL进程——服务没启动、端口没监听、防火墙拦了,三者占九成以上。
MySQL服务压根没在运行
这是最常被跳过的一步。报错时别急着改配置,先确认mysqld进程是否真在跑:
- Linux执行
systemctl status mysql或systemctl status mysqld(不同发行版服务名不同),看状态是不是active (running);若显示inactive或failed,直接启动:sudo systemctl start mysql - Windows打开
services.msc,找MySQL或MySQL80,右键“启动” - 启动失败?立刻查日志:
journalctl -u mysql -n 50 -e(systemd系统)或翻log-error配置项指定的文件路径,常见卡点有 datadir 权限不对、pid 文件残留、InnoDB 表损坏
MySQL监听地址设成了127.0.0.1
服务起来了,但只绑定了本地回环地址,外部请求自然被内核拒绝:
- 登录MySQL执行
SHOW VARIABLES LIKE 'bind_address';,如果返回127.0.0.1,就坐实了这个问题 - 编辑配置文件(
/etc/mysql/mysql.conf.d/mysqld.cnf或/etc/my.cnf),找到[mysqld]段,把bind-address = 127.0.0.1改成bind-address = 0.0.0.0(允许所有IP)或具体外网IP - 改完必须重启:
sudo systemctl restart mysql,然后验证:ss -tlnp | grep :3306应该看到*:3306或:::3306,而非127.0.0.1:3306 - 注意:Docker容器内连宿主机MySQL,别用
localhost,要用host.docker.internal(Mac/Win)或宿主机真实IP(Linux)
防火墙或云平台安全组没放行3306
即使MySQL监听了0.0.0.0,中间网络设备照样能掐断连接:
- 本地测试用
nc -zv 127.0.0.1 3306确认本机通;再从客户端机器执行nc -zv your_server_ip 3306,若超时,就是网络层阻断 - Linux服务器检查防火墙:
sudo ufw status(Ubuntu)或sudo firewall-cmd --list-ports(CentOS),没开3306就加:sudo ufw allow 3306 - 阿里云/腾讯云等,必须进控制台→安全组→入方向规则,添加一条:类型 MySQL,端口 3306,源IP填客户端IP或
0.0.0.0/0(测试用,勿长期开放) - 企业内网还可能遇到交换机ACL、堡垒机策略,需协同网络管理员排查
用户权限和认证插件不匹配(容易误判为Connection refused)
极少数情况下,错误表现类似Connection refused,实则是认证阶段崩溃:
- MySQL 8.0+ 默认用
caching_sha2_password插件,但旧版mysqlclient或某些PHP扩展不支持,连接会卡在握手阶段,部分客户端表现为超时或拒绝 - 临时解决:登录MySQL执行
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_pass'; FLUSH PRIVILEGES; - 长期方案:升级驱动(如Python用
pymysql,Java用mysql-connector-java 8.0.23+) - 注意:授权语句中的
host必须精确匹配来源IP,'user'@'192.168.1.%'无法匹配192.168.2.100
真正卡住人的地方,往往不是技术多复杂,而是排查顺序错了——先验服务状态和端口监听,再动权限和配置。很多人花两小时调 GRANT 语句,却漏看了 systemctl status 里那行醒目的 failed。


















