根本原因是连接池配置失当、应用未释放连接及MySQL超时设置不匹配——三者叠加导致Sleep连接堆积,而非max_connections过小;需通过Threads_connected与Threads_running对比确认真实负载,优先优化应用层连接池参数与wait_timeout协同。

根本原因不是连接数设得太低,而是连接池没撑住、应用没管好连接、MySQL自身配置又没兜底——三者叠加导致线程耗尽表象。
max_connections 配得太小只是表象,不是根因
看到 Too many connections 就急着调大 max_connections,容易引发 OOM 或上下文切换风暴。每个连接在 MySQL 侧平均吃掉 4–10MB 内存,设到 2000 以上而物理内存只有 32GB,mysqld 很可能被系统 OOM killer 杀掉。
- 先查真实活跃连接:
SHOW STATUS LIKE 'Threads_connected';和SHOW STATUS LIKE 'Threads_running';—— 如果Threads_running长期低于 50,说明瓶颈不在连接数,而在查询执行或锁等待 - 确认是否真被拒绝:抓取应用日志里报错是否含
Too many connections;若报的是Communications link failure或超时,则大概率是连接池或网络问题 - 安全上限参考:设为
max_connections = (服务器总内存 GB × 100) / 8(例如 16GB 内存 → 建议 ≤ 200),再结合应用实例数和每实例预估并发连接反推
应用端连接池配置不当才是高频真凶
MySQL 5.7 默认能稳扛 300+ 活跃连接,但如果你的应用用 HikariCP 却只配了 maximumPoolSize=10,QPS 上 200 时所有线程都在池外排队,等不到连接就直接超时——这时 Threads_connected 可能才 20,但用户已大面积报错。
- 务必设
minimumIdle ≥ maximumPoolSize × 0.3:避免低峰期连接全释放,高峰期握手 + TLS + 认证耗时叠加,触发connection-timeout - 禁用
testOnBorrow(HikariCP 已移除,Druid 默认关):否则每次getConnection()都发SELECT 1,QPS=1000 就等于平白多出 1000 QPS 无效查询 - 连接字符串加
&socketTimeout=30000:防个别慢查询拖垮整个池;同时确保wait_timeout≥ 连接池空闲回收周期(如池设 60s 回收,则 MySQL 至少设wait_timeout=90)
sleep 连接堆积会悄悄吃光连接名额
大量 Sleep 状态连接不等于“空闲可用”,它们占着 Threads_connected 名额却不干活,最终把新请求堵在外面。常见于 PHP pconnect、Java 忘记 close()、或事务未提交/回滚后连接归还但状态残留。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 查堆积:
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE FROM information_schema.PROCESSLIST WHERE COMMAND = 'Sleep' AND TIME > 60; - 服务端自动清理:在
[mysqld]段配wait_timeout=120和interactive_timeout=120,重启或运行SET GLOBAL wait_timeout = 120; - 别写定时 kill 脚本:手动
KILL正在事务中的 Sleep 连接可能丢数据,且治标不治本
innodb_buffer_pool_instances=1 会加剧线程争抢
当 innodb_buffer_pool_instances 为 1 时,所有读请求都要抢同一把 buf_pool_mutex,导致大量线程卡在缓冲池查找阶段,表现为 Threads_running 低、CPU 单核满、Threads_connected 却持续上涨——看起来像连接不够,实则是线程全堵在入口处动不了。
- 验证:
SELECT @@innodb_buffer_pool_instances;,若为 1 且innodb_buffer_pool_size > 1G,基本就是它 - 修复:设为 8(或与 CPU 核数对齐),但必须满足
innodb_buffer_pool_size % (innodb_buffer_pool_chunk_size × instances) == 0,否则 MySQL 启动时会向上取整,极易 OOM - 附带检查
btr_search_latch:高并发等值查询下,adaptive hash index 的全局 latch 也可能成新瓶颈,SHOW ENGINE INNODB STATUS\G中看SEMAPHORES段是否频繁出现btr0sea.cc
连接线程耗尽从来不是单一参数问题。最易被忽略的是:应用层连接未归还、连接池最小空闲数为 0、MySQL 的 wait_timeout 小于连接池回收间隔——这三个条件只要凑齐两个,生产环境早晚出事。










