真实连接压力看Threads_running而非Threads_connected;Threads_connected反映当前总连接数(含空闲),Threads_running才是正在执行SQL的线程数,Max_used_connections记录历史峰值,三者结合才能准确评估压力。

别直接改配置文件就重启,先看真实连接压力在哪——Max_used_connections 接近 max_connections 才说明真要扩容;如果 Threads_connected 高但 Threads_running 很低,大概率是应用没配好连接池或 wait_timeout 太大。
怎么看当前连接是不是真忙?
只查 SHOW VARIABLES LIKE 'max_connections' 没用,得盯三个状态值:
-
Threads_connected:当前挂着的连接总数(含 Sleep) -
Threads_running:此刻正在执行 SQL 的线程数(这才是真实并发压力) -
Max_used_connections:自上次启动以来的历史峰值
常见错误现象:Too many connections 报错,但 SHOW PROCESSLIST 里全是 Sleep 状态、Time 列几百上千秒——这说明连接没释放,不是并发高,是空闲连接卡着不走。
怎么算一个安全又够用的值?
按内存估算比拍脑袋靠谱得多。每个连接至少吃掉 256KB~4MB 内存(取决于 sort_buffer_size、read_buffer_size 等),16GB 内存服务器保守按每连接 1MB 算,理论硬上限约 10000,但生产环境不建议碰这个数。
- 小内存机器(≤4GB):设 ≤500
- 常规生产服务器(8–16GB):从 500–1000 起步,观察 1–2 天监控再微调
- 若
Max_used_connections持续在 780 左右,可设为 1000(留 20% 余量);若冲到 950,优先查应用层连接泄漏,而不是直接拉到 1200 - 必须同步检查系统级限制:
ulimit -n要 ≥max_connections × 2,否则 MySQL 启动时会静默降级,日志里可能只写Could not increase number of max_open_files
改完要不要重启?两种方式行为完全不同
动态改和永久改不是“选哪个更方便”,而是“哪个更可控”:
- 临时改:
SET GLOBAL max_connections = 1000—— 立即生效,但 MySQL 重启后回退;适合测试环境快速验证,或应急扩容几小时 - 永久改:在
/etc/my.cnf的[mysqld]段加max_connections = 1000,然后systemctl restart mysqld—— 生产环境唯一推荐方式,避免配置漂移或权限失败(某些旧版本SET GLOBAL可能因插件或权限被拒绝) - 注意:
max_connections上限是 16384,超过也按 16384 算,别设 20000
为什么调了 max_connections 还是连不上?
最常漏掉的点,往往比参数本身还关键:
-
wait_timeout和interactive_timeout默认是 28800 秒(8 小时),连接池没配好时,大量空闲连接长期占坑,max_connections再大也白搭 - 应用没启用连接池(比如裸用
mysql.connect()),每次请求新建连接,很快耗尽限额 - 没配
thread_cache_size,连接频繁创建销毁,CPU 毛刺明显,Threads_created持续上涨 -
skip_name_resolve = ON没开,DNS 反查失败会导致新连接卡在Connecting to localhost几秒甚至十几秒,看起来像连接慢或连不上
真正难的不是把数字调大,而是让每个连接进来之后能快速干活、干完就走、不卡位、不抢资源。很多线上连接问题,根子不在数据库配置,而在应用代码里少关了一个 Connection,或多开了一个没加 LIMIT 的全表查询。











