max_connections不应设为整数大数,而应基于历史峰值、内存余量和系统限制交叉验证后定值,推荐起步设400并同步调低wait_timeout;须写入my.cnf的[mysqld]段重启生效,且ulimit -n≥max_connections+200。

直接说结论:max_connections 不该设成整数大数(比如 1000 或 65535),而应基于历史峰值、内存余量和系统限制三者交叉验证后定值,推荐起步设为 400,并同步调低 wait_timeout。
查历史峰值再定目标值
盲目调高只会触发 OOM killer 杀掉 mysqld 进程。真实瓶颈往往不在连接数本身,而在每连接内存开销(sort_buffer_size、read_buffer_size 等线程级变量会动态放大)。
- 先看历史最高用过多少:
SHOW STATUS LIKE 'Max_used_connections';,这个值是你最可靠的下限参考 - 再算应用侧总池容量:比如 HikariCP 的
maximumPoolSize=50× 8 个实例 = 400,加 30% 余量 ≈ 520 - 最后兜底估算内存:假设每连接均占 4MB,16GB 内存服务器理论硬上限约 4000,但线上建议不超 500
永久修改必须写进 my.cnf 的 [mysqld] 段
SET GLOBAL 只是临时手段,MySQL 重启后就回退——尤其在容器或 systemd 环境下容易被忽略。
- 确认配置文件路径:
mysql --help | grep "Default options",常见位置是/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf - 只在
[mysqld]段下添加:max_connections = 400,写在[client]或其他段完全无效 - 如果用 systemd,检查
/etc/systemd/system/mysqld.service.d/override.conf是否覆盖了配置 - 改完必须重启:
sudo systemctl restart mysql,否则不生效
别忘了操作系统层的 ulimit 限制
MySQL 启动时若发现 ulimit -n 小于 max_connections + 200,可能启动失败,或运行中突然崩溃。
- 查当前限制:
cat /proc/$(pidof mysqld)/limits | grep "Max open files" - 临时提升:
ulimit -n 65535 - 永久生效:在
/etc/security/limits.conf中加两行:mysql soft nofile 65535和mysql hard nofile 65535 - 注意:Docker 容器需显式传
--ulimit nofile=65535:65535,否则宿主机设置不继承
wait_timeout 不调低,max_connections 就是假上限
默认 28800 秒(8 小时)会让“假死连接”长期占坑,最终报错 ERROR 1040 (08004): Too many connections,但实际活跃查询可能只有几个。
- 生产环境建议统一设为
wait_timeout = 600和interactive_timeout = 600(10 分钟) - 这两个参数必须写进
[mysqld]段并重启,SET GLOBAL 对已建立连接无效 - 应用端必须确保调用
connection.close()或使用带validationQuery的连接池,否则超时只是延缓问题
真正卡住的从来不是 max_connections 数字本身,而是连接生命周期管理是否闭环、系统资源是否对齐、以及有没有把压力错误地推给数据库而不是优化应用层复用或读写分离。


















