不能靠调高max_connections防止连接占满,需查清是否真缺连接或存在泄漏;通过show status和show processlist定位sleep超时、长query、同host/user的异常连接;临时可kill+动态调参,但须同步调整系统文件描述符限制;根本解法是设wait_timeout、用连接池、加proxysql分流。

不能靠调高 max_connections 来防止连接被占满——它只是把崩溃点往后推,不解决连接生命周期失控的根本问题。
查清楚是不是真缺连接,还是连接用完不释放
执行 SHOW STATUS LIKE 'Threads_connected'; 看当前活跃连接数;再跑 SHOW PROCESSLIST;,重点关注状态为 Sleep 且 Time 超过 60 秒的行。这类连接大概率是应用没调 close()、或连接池配置漏设超时参数导致的“僵尸连接”。
- 如果
Threads_connected持续在max_connections的 80% 以上波动,说明连接复用率低或泄漏已发生 -
Command列为Query且Time很长,要立刻查对应 SQL 是否没索引、是否锁表 - 多个连接来自同一
Host+ 同一User,基本可定位到具体服务实例
临时救急:KILL 异常连接 + 动态调参(仅限 SUPER 权限)
当已无法登录时,优先用 MySQL 预留的管理连接(如 extra_port,Percona/MariaDB 支持)或系统级手段进入。确认后快速清理:
- 杀掉明显异常的连接:
KILL <em>id</em>;(id 来自PROCESSLIST第一列) - 运行时提升上限(重启失效):
SET GLOBAL max_connections = 500; - 别忘了同步调
max_user_connections,防止单个用户吃光全部配额
注意:SET GLOBAL 不会自动刷新系统文件描述符限制,若 OS 层 Max open files 小于新值 + 50,MySQL 可能静默降级或启动失败。
永久生效必须改配置 + 同步调系统限制
只改 /etc/my.cnf 的 [mysqld] 段加 max_connections = 500 不够,Linux 下 MySQL 进程受 systemd 或 ulimit 约束:
- systemd 用户需编辑
/usr/lib/systemd/system/mysqld.service,加两行:LimitNOFILE=10000和LimitNPROC=10000,再执行systemctl --system daemon-reload && systemctl restart mysqld - 非 systemd 环境需在
/etc/security/limits.conf中为mysql用户设soft nofile 65535和hard nofile 65535 - 验证是否真正生效:
SHOW VARIABLES LIKE 'max_connections';,不是SHOW STATUS LIKE 'Max_used_connections';
比调参更关键的三件事:超时、池化、分流
很多团队卡在“调了 max_connections 还是满”,其实是没动连接本身的行为逻辑:
- 强制空闲连接退出:在 MySQL 配置中设
wait_timeout = 120和interactive_timeout = 120,避免 Sleep 连接长期占坑 - 应用层必须用连接池:Java 选
HikariCP、Go 用database/sql默认池、Node.js 用mysql2.createPool,禁用手写长连接循环 - 前置代理分流:ProxySQL 能自动 kill 超时连接、拦截慢查询、按权重分发读请求,比硬扛连接数更稳
连接数从 400 增到 500 时响应时间可能不变,但从 500 到 550 就可能陡增——这个拐点往往被监控忽略,因为 Threads_connected 是瞬时快照,没人盯它的变化斜率。











