MySQL报错“Too many connections”表示连接数超限而非服务宕机,新连接被直接拒绝;需先查当前连接数、定位活跃/长Sleep连接及异常用户,再结合内存与负载审慎调整max_connections,并重点排查应用层连接泄漏。

MySQL报错 Too many connections 说明连接数已超限,不是服务宕了,而是新连接被直接拒绝
这个错误出现时,mysqld 仍在运行,但所有新来的连接(比如应用重试、健康检查、开发连客户端)都会立刻收到 ERROR 1040 (HY000): Too many connections。关键不是“连不上数据库”,而是“连不进当前实例”——得先确认是真并发高,还是连接泄漏或配置过小。
查当前连接数和活跃连接,别只看 max_connections 配置
很多同学一看到报错就去改 max_connections,结果调大后几天又爆了。真正该先做的是定位谁在占连接:
- 登录 MySQL 后执行
SHOW STATUS LIKE 'Threads_connected';看当前总连接数 - 执行
SHOW PROCESSLIST;或SELECT * FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep';找出非 Sleep 状态的活跃查询(尤其是运行时间长、没加索引的) - 重点看
TIME列:持续几百秒以上的Sleep连接,大概率是应用没正确关闭连接(如忘记conn.close()或连接池配置不当) - 用
SELECT USER, HOST, COUNT(*) FROM information_schema.PROCESSLIST GROUP BY USER, HOST;看是不是某个应用 IP 或账号异常占满连接
调整 max_connections 要结合内存与实际负载,不是越大越好
每个连接默认占用约 256KB–2MB 内存(取决于排序缓冲、临时表大小等),盲目调高会导致 OOM 或系统变慢:
- 临时生效(重启失效):
SET GLOBAL max_connections = 512;(需有SUPER权限) - 永久生效:在
my.cnf的[mysqld]段下加一行max_connections = 512,然后重启mysqld - 注意:如果使用云数据库(如阿里云 RDS、AWS RDS),该参数通常受限于实例规格,不能随意调高,需在控制台修改或升级规格
- 建议值参考:普通 4C8G 自建库可设为 300–500;连接池最大数(如 HikariCP 的
maximumPoolSize)应 ≤max_connections的 70%,留余量给后台线程和管理员连接
长连接不释放?重点检查应用层连接池和超时配置
90% 的 Too many connections 根源不在 MySQL,而在应用没回收连接。常见坑点:
- Java 应用用 HikariCP 时,
connection-timeout默认 30 秒,但若数据库响应慢或网络抖动,连接可能卡在获取阶段,堆积等待;建议设为 10–15 秒,并打开leak-detection-threshold - PHP 的
mysqlnd默认复用连接,但若脚本异常退出(如 fatal error),连接不会自动归还池中;建议配合mysqli::close()显式释放,或启用mysqlnd_ms的自动清理 - Python 的
pymysql或mysql-connector-python若未用上下文管理器(with conn:)或漏掉cursor.close()+conn.close(),连接会一直挂到超时(默认 wait_timeout=28800 秒,即 8 小时) - 务必检查
wait_timeout和interactive_timeout:它们控制空闲连接存活时间,建议设为 300–600 秒(5–10 分钟),避免 Sleep 连接长期霸占名额
真正难处理的不是调参,是区分“合理高并发”和“连接泄漏”。前者要扩容+优化 SQL,后者必须从应用日志、连接池监控、SQL 审计入手——否则每次调大 max_connections,只是把问题延迟爆发而已。


















