mysql连不上首要排查监听与防火墙:先确认systemctl status mysqld为active(running),再用ss -tlnp | grep :3306验证是否监听0.0.0.0:3306;若仅127.0.0.1则需修改my.cnf中bind-address为0.0.0.0并重启;接着按实际防火墙工具(firewalld或iptables)精准放行3306/tcp端口并重载规则,最后用nc -zv测试端口连通性。

MySQL连不上,八成不是密码错,而是3306端口被防火墙拦了——但直接开3306不等于能连上,得先确认 MySQL 本身监听的是谁、再选对防火墙工具、最后验证规则是否生效。
确认 mysqld 真正在监听 3306 且对外可访问
防火墙只是最后一道关,如果 MySQL 自己只绑定了 127.0.0.1,那开了端口也没用。
- 运行
systemctl status mysqld或systemctl status mysql,确保状态是active (running) - 执行
ss -tlnp | grep :3306,输出里必须包含*:3306或0.0.0.0:3306;如果只有127.0.0.1:3306,说明配置文件里bind-address = 127.0.0.1没改 - 修改
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf,把bind-address改成0.0.0.0(或具体内网 IP),然后systemctl restart mysqld
区分 firewalld 和 iptables:别用错命令
CentOS/RHEL 7+ 默认用 firewalld,Ubuntu/Debian 多用 iptables(或 nftables)。混用命令会导致规则不生效。
- 查当前用的什么:
systemctl list-unit-files | grep -E "firewalld|iptables",看哪个是enabled - 如果是
firewalld:
– 永久放行:firewall-cmd --add-port=3306/tcp --permanent
– 重载:firewall-cmd --reload
– 验证:firewall-cmd --list-ports应该输出3306/tcp - 如果是
iptables:
– 编辑/etc/sysconfig/iptables(RHEL系)或用命令临时加:iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
– 规则必须加在-j REJECT或-j DROP之前,否则无效
– 保存并重启:service iptables save && service iptables restart
不要依赖 --add-service=mysql
这个命令看似省事,但实际风险高:
-
mysqlservice 在多数系统里根本没定义,firewall-cmd --list-services输出里通常没有它 - 即使有,它的端口可能不是 3306(比如某些定制镜像里指向 3307)
- 硬写端口更可控:
firewall-cmd --add-port=3306/tcp --permanent是唯一推荐写法
验证端口是否真正通了
别只信 firewall-cmd --list-ports,它只说明规则加了,不代表流量能过。
- 从本机测:
nc -zv 127.0.0.1 3306(应返回succeeded!) - 从另一台机器测:
nc -zv 3306,不通就说明防火墙或网络层还有问题 - 注意:MySQL 用户权限也要配好,
GRANT ... ON *.* TO 'user'@'%' IDENTIFIED BY 'pass';+FLUSH PRIVILEGES;缺一不可
最容易被忽略的是 bind-address 和防火墙工具的对应关系——改了 my.cnf 却没重启服务,或用了 iptables 命令却在跑 firewalld,这两类错误占实际连不上问题的七成以上。











