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

max_connections 不是并发能力的开关,而是资源水位线——设高了压垮内存,设低了直接拒连。
怎么看当前连接压力是否真实?
别只看 SHOW VARIABLES LIKE 'max_connections',那只是个数字。真正要盯的是三个状态值:
-
Threads_connected:当前有多少连接挂着(含空闲) -
Threads_running:此刻真正在干活的连接数 -
Max_used_connections:自上次启动以来的历史峰值
如果 Threads_connected 长期 > 80% 的 max_connections,但 Threads_running 常年 wait_timeout 太大导致“僵尸连接”堆积;如果 Max_used_connections 接近甚至等于 max_connections,说明已经踩线,必须干预。
怎么算一个安全又够用的值?
按内存算比按CPU核心数更靠谱,因为每个连接至少吃掉 256KB~4MB 内存(取决于 sort_buffer_size、read_buffer_size 等)。例如:
- 16GB 内存服务器,保守按每连接 4MB 算 → 硬上限约 4000,但不建议碰这个数
- 线上稳态推荐从
300–500起步,观察 1–2 天监控再微调 - 若
Max_used_connections持续在 420 左右,可设为500;若冲到 780,就该查应用层连接泄漏,而不是直接拉到 1000
注意:max_connections 受操作系统 ulimit -n 限制,MySQL 启动时若报 Can't create thread (errno 11) 或日志里有 Too many open files,先检查并调高系统级文件描述符限制。
改完要不要重启?临时改和永久改的区别
两种方式都有效,但行为不同:
- 动态改:
SET GLOBAL max_connections = 500—— 立即生效,但 MySQL 重启后回退到配置文件值(某些旧版本如 5.6 还可能因权限或插件问题失败) - 永久改:在
/etc/my.cnf的[mysqld]段落加max_connections = 500,然后systemctl restart mysqld
生产环境优先走配置文件+重启,避免动态设置被意外覆盖或失效;测试环境可先动态试水,确认无异常再固化。
为什么调了 max_connections 还是连不上?
常见漏点比参数本身还关键:
-
wait_timeout和interactive_timeout默认 28800 秒(8 小时),连接池没配好时,大量空闲连接长期占坑,max_connections再大也白搭 - 应用没启用连接池(比如裸用
mysql.connect()),每次请求新建连接,很快耗尽限额 - 没配
thread_cache_size,连接频繁创建销毁引发 CPU 抖动,间接拖慢响应,让人误判为“连不上”
真正卡住的往往不是 max_connections 这个数字,而是它背后那一整条连接生命周期管理链——从应用发起到数据库释放,任何一环松动,调参都只是补漏。











