max_connections不能防爆破,仅限制并发总量;真正有效的防护需系统层(iptables限速)、代理层(proxysql限流)和mysql层(max_connect_errors配合host_cache)协同实现。

max_connections 不能防爆破,它只管总量不拦来源
调高 max_connections 对暴力连接尝试完全无效。MySQL 的 max_connections 是并发连接数上限,不是“每 IP 每秒允许几次连接”的防火墙规则。攻击者用脚本每秒建 100 个短连接(连上就断),max_connections 还没满,但 Threads_connected 已频繁抖动、Aborted_connects 猛涨,服务已卡顿甚至触发系统级文件描述符耗尽。
真正起作用的是三层协同:
- 系统层:用
iptables或firewalld限同一 IP 新建连接速率(如每秒 ≤3 个) - 代理层:用
ProxySQL或HAProxy做连接准入和 SQL 级限流(如某用户每秒最多 5 条 SELECT) - MySQL 层:靠
max_connect_errors防密码爆破,但对空密码/弱密码/端口扫描无效
max_connect_errors 配合 host_cache 才能真起效
max_connect_errors 默认是 100,意思是同一个 IP 连续认证失败 100 次后,MySQL 会把它加入 host_cache 黑名单,后续连接直接拒绝并报错:Host 'x.x.x.x' is blocked because of many connection errors。
但这个机制有硬伤:
- 它只统计“认证失败”,不区分是输错密码、账号不存在,还是 TCP 握手失败——网络抖动或客户端 bug 也会被误记
-
host_cache不持久,MySQL 重启就清空;且默认缓存大小有限(table_open_cache和host_cache_size共同影响) - 若应用用了连接池且配置了重试,一次失败可能触发多次重连,快速打满计数器
实操建议:
- 先查当前值:
SHOW VARIABLES LIKE 'max_connect_errors'; - 生产环境建议设为 50~100,别盲目调低(否则易误封正常用户)
- 配合监控
Aborted_connects和Host_blocked_by_host_cache,发现突增时立刻查SELECT * FROM performance_schema.host_cache; - 临时解封命令:
FLUSH HOSTS;(慎用,会清空所有缓存)
为什么 set global max_connections 经常失效
执行 SET GLOBAL max_connections = 2000; 后立刻查仍是 151?常见原因有三个:
- 操作系统级限制卡死:systemd 默认
LimitNOFILE=1024,MySQL 启动时发现 ulimit -n 只有 1024,就会默默把max_connections截断到 ≈1024×0.8(留 buffer),你设 5000 也白搭 - MySQL 编译硬上限:5.7/8.0 默认上限是 100000,超了会报
ERROR 1238 (HY000): Variable 'max_connections' is a read only variable - 配置未持久化:该命令只在当前进程生命周期有效,MySQL 一重启就回退到配置文件值
正确做法是三步同步改:
- 改 systemd service 文件:
/etc/systemd/system/mysqld.service中加LimitNOFILE=65536 - 改 MySQL 配置:
/etc/my.cnf的[mysqld]段里写max_connections = 2000 - 改完 reload:
systemctl daemon-reload && systemctl restart mysqld
连接数爆满时优先查 Threads_connected 而不是 max_connections
max_connections 是天花板,Threads_connected 才是你此刻真实占用的“房间数”。很多团队一见报错就急着调高 max_connections,结果内存暴涨、OOM 崩溃,却没发现 Threads_connected 长期只有 80,而 Max_used_connections 最高才 120 —— 说明根本没压到上限,问题出在连接没释放。
关键指标含义:
-
SHOW STATUS LIKE 'Threads_connected';:当前活着的连接数(含 sleep) -
SHOW GLOBAL STATUS LIKE 'Max_used_connections';:自启动以来历史最高并发连接数 -
SHOW PROCESSLIST;:看有没有大量Sleep状态连接,再结合Time列判断是否超时未释放
如果 Threads_connected 高但 Max_used_connections 低,大概率是应用没 close 连接;如果两者都高且持续上涨,要查慢查询和长事务。
别只盯着 max_connections 调数字,先看清连接到底卡在哪一层:是应用没关、是慢 SQL 占着、是 DNS 反向解析卡住握手、还是系统 ulimit 拦着——这些比调参更关键。











