答案是需先查max_used_connections历史峰值、核对应用连接池总规模,再同步调ulimit、systemd限制及wait_timeout等参数,而非盲目调高max_connections。

别直接改 max_connections 就完事——它只是连接链最末端的闸门,前面卡住一个环节,调再大也没用。
查清历史峰值和当前占用,再决定要不要调
盲目加到 2000 或 5000 很可能掩盖真实问题,比如连接泄漏或连接池配置失配。
- 先看历史最高值:
SHOW STATUS LIKE 'Max_used_connections';—— 如果长期稳定在 180,max_connections=151就是瓶颈;如果曾冲到 320,那 400 是合理起步 - 再看实时占用:
SHOW STATUS LIKE 'Threads_connected';和SHOW PROCESSLIST;—— 注意Command列是不是大量Sleep,且Time超过 300 秒,这基本就是空闲连接没释放 - 结合应用侧连接池总容量估算:比如 4 个服务实例 × HikariCP
maximumPoolSize=100= 400,再加 30% 余量 → 建议设max_connections=500
必须同步调低 wait_timeout 和 interactive_timeout
这两个参数默认 28800 秒(8 小时),是连接数爆满的隐形推手。应用端连接未 close,MySQL 就一直挂着它,直到超时才回收。
- 生产环境建议统一设为
wait_timeout = 600、interactive_timeout = 600(10 分钟) - 这个值必须小于客户端连接池的
idle-timeout(如 HikariCP 的idle-timeout=300000即 5 分钟),否则 MySQL 先断,应用拿到的是失效连接 - 改完后观察
Threads_connected是否明显回落,若仍堆积,说明应用层有连接未归还
系统级限制不放开,MySQL 根本起不来
max_connections 不是 MySQL 自己说了算,操作系统文件描述符(file descriptor)数量必须兜底。
- 检查当前限制:
cat /proc/$(pgrep mysqld)/limits | grep "Max open files" - 必须确保
ulimit -n≥max_connections + 200(留出日志、表缓存等开销) - 在
/etc/security/limits.conf中加两行:mysql soft nofile 65535mysql hard nofile 65535 - systemd 环境下还要确认
/etc/systemd/system/mysqld.service.d/limits.conf没覆盖掉上述设置
别碰 thread_pool_size,社区版不支持
网上很多教程教你在 my.cnf 里加 thread_pool_size = 16 或 thread_handling = pool-of-threads,这在 MySQL 社区版(5.7/8.0)完全无效。
- 执行
INSTALL PLUGIN thread_pool SONAME 'thread_pool.so';会报错:Unknown plugin 'thread_pool' - 配置项会被忽略,启动日志里只有警告,容易被漏看
- 真正可用的轻量替代是
thread_cache_size:缓存空闲线程供新连接复用,推荐值为ceil(max_connections / 16),但一般不超过 16
最容易被忽略的一点:MySQL 启动时会校验 max_connections、table_open_cache 和 open_files_limit 三者的逻辑关系。比如你设了 max_connections = 2000,但 table_open_cache = 400(默认值),MySQL 实际生效的连接数可能被截断到几百——这个隐性限制连 SHOW VARIABLES 都不会明说。











