mysql连接被拒绝时,应先通过systemctl检查服务状态、netstat确认端口监听、socket连接验证服务是否正常,再查错误日志(配置文件、journalctl)、系统资源限制(open_files_limit)、selinux/firewalld拦截,最后排查docker等环境问题。

mysql连接被拒绝时,先确认是网络层还是MySQL服务层问题
连接被拒绝(Connection refused)绝大多数情况不是密码或权限错,而是MySQL根本没在监听、没启动,或者被防火墙/SELinux拦了。别急着改my.cnf,先快速分层定位:
- 用
systemctl status mysqld(或mysql-server,取决于发行版)看服务是否 active(running);如果显示 inactive 或 failed,跳过所有配置检查,先解决启动失败 - 运行
netstat -tlnp | grep :3306(或你配的端口),确认mysqld进程是否真在监听。没有输出?说明 MySQL 没绑定端口——可能bind-address配错了,或skip-networking被启用了 - 本地用
mysql -u root -S /var/lib/mysql/mysql.sock尝试 socket 连接。能连上?说明服务本身正常,问题出在网络栈(防火墙、bind-address、远程访问权限)
查看MySQL错误日志前,得先知道它到底写在哪
MySQL 启动失败或拒绝连接时,错误日志是唯一可靠线索,但它的位置不固定,不能默认去 /var/log/mysqld.log 猜:
- 先查配置:运行
mysqld --verbose --help 2>/dev/null | grep "default log" | head -1,或直接看my.cnf里有没有log-error项;常见路径有/var/log/mysqld.log、/var/log/mysql/error.log、/usr/local/mysql/data/hostname.err - 如果配置里没设
log-error,且 MySQL 是 systemd 启动的,日志很可能走 journal:用journalctl -u mysqld -n 50 -e查最近 50 行,重点找Can't start server、Address already in use、Table 'mysql.plugin' doesn't exist这类关键报错 - 注意权限:如果日志文件所在目录属主不是
mysql用户,或mysqld没写入权限,它会静默失败——连日志都写不了,此时journalctl就更关键
系统资源限制常被忽略,尤其是 open_files_limit 和 max_connections
MySQL 启动后突然拒绝新连接,或只允许极少数连接,大概率是系统级资源卡死了,和 MySQL 配置关系不大:
- 检查当前限制:
cat /proc/$(pgrep mysqld)/limits | grep "Max open files",对比my.cnf里的open_files_limit;如果实际值远小于配置值,说明 systemd 或 ulimit 拦住了——要改/etc/systemd/system/mysqld.service.d/override.conf里的LimitNOFILE=65536 -
max_connections不是孤立参数:它受table_open_cache、innodb_open_files等联动影响;若设了 1000 但open_files_limit只有 1024,MySQL 会自动调低max_connections并在错误日志里写Changed limits: max_open_files: 1024 max_connections: 214 table_cache: 400 - 临时测试可加
--skip-grant-tables启动,绕过权限检查;但仅用于排障,绝不可长期启用
SELinux 或 firewalld 拦截连接时的表现和验证方式
CentOS/RHEL 系统上,Connection refused 很可能是 SELinux 默默拒绝了网络 bind,而不是端口不通:
- 快速验证:临时关 SELinux
setenforce 0,再试连接;如果立刻通了,就是 SELinux 策略问题。别直接禁用,用ausearch -m avc -ts recent | grep mysqld查拒接记录,然后audit2why分析,最后audit2allow -M mysql_local_bind生成策略 - firewalld 常见漏点:开了
publiczone 却没开mysqlservice,或只放行了3306/tcp却忘了3306/udp(虽 MySQL 不用 UDP,但某些 firewalld 版本规则匹配逻辑会误判);用firewall-cmd --list-all确认ports:或services:里有mysql - 注意:Docker 容器内跑 MySQL 时,宿主机 firewalld + 容器 --network=host 组合容易导致端口看似开放实则被拦,优先用
docker run -p 3306:3306模式并检查容器内netstat
真正卡住人的,往往不是配置写错,而是错误日志压根没写出来、或写了但没人去看;又或者 systemctl restart mysqld 成功了,但进程早因资源不足崩在启动中途——这时候 journalctl 和 /proc/*/limits 比任何文档都管用。











