thread_cache_size必须手动设置,否则默认0导致频繁创建线程;通过threads_created每秒增量>1–2和threads_cached长期为0可判断缓存未生效。

thread_cache_size 不设就是默认 0,短连接每秒建一次线程,CPU 和上下文切换开销直接拉满——必须手动设值,且不能只调这一个参数。
怎么看当前线程缓存是否生效
先查两个关键状态变量,别凭感觉调:
-
SHOW STATUS LIKE 'Threads_created';—— 每秒新增值 > 1–2,说明线程频繁重建,缓存明显不足 -
SHOW STATUS LIKE 'Threads_cached';—— 长期为 0 或始终 wait_timeout 太小(比如设成 30),连接在进缓存前就被 kill 了 -
SHOW STATUS LIKE 'Threads_connected';波动剧烈(例如 5 → 200 → 10),基本可断定应用层连接未释放,不是配置问题而是代码缺陷
thread_cache_size 设多少才合适
没有“按内存算”的固定公式,真实场景靠观察反馈:
- 如果
Threads_created每秒新增 ≤ 1,Threads_cached稳定在 3–6,thread_cache_size = 8就够用 - 短连接 QPS 高(如 PHP-FPM 场景)、突发流量多,先设
thread_cache_size = 16,再看Threads_cached是否长期卡在 16(说明已满,可微调) - 设到 32 以上基本无效:每个空闲线程占 256KB–1MB 内存,缓存 64 个线程就吃掉 64MB+,但 MySQL 内部管理开销反而上升
-
max_connections必须同步检查:若SHOW STATUS LIKE 'Aborted_connects';持续增长,说明大量连接连认证都失败(密码错、host 不符),加缓存毫无意义
为什么设了 thread_cache_size 还没效果
缓存不生效,90% 是环境或客户端行为问题:
- 客户端没调
conn.close()(Python/Java)或mysqli_close()(PHP),而是靠超时断开或进程退出,MySQL 收不到 FIN,线程直接销毁 - 中间件(如 HAProxy、Nginx)开了 TCP keepalive 但没透传 FIN 包,MySQL 认为连接还活着,不进缓存队列
-
wait_timeout或interactive_timeout设得太小( - Linux 内核限制(如
ulimit -n或net.core.somaxconn)没调,导致 MySQL 根本无法创建足够线程,thread_cache_size再大也无从缓存
真正卡顿在 200ms 左右波动?大概率是 thread_cache_size 不足 + wait_timeout 过短的组合问题。线程刚缓存下来,几秒后就被清掉,下次请求又得重建——这不是调参能救的,得从连接生命周期源头看起。











