max_connections 是只读全局变量,show variables 显示151说明配置未生效,常见原因包括配置文件路径错误、段落写错、语法错误、systemd资源限制未同步;永久生效需按set persist、配置文件修改、启动参数顺序检查并验证os限制与线程缓冲区。

max_connections 不是“系统变量”意义上的可自由设置项——它是个只读全局变量,真实生效值由配置文件、启动参数或持久化写入共同决定,且受操作系统限制硬约束。
为什么 SHOW VARIABLES 显示的 max_connections 总是 151?
这不是 MySQL 忘记你改了,而是它根本没读到你的配置。常见原因包括:
- 改错了配置文件:执行
mysqld --verbose --help | grep "Default options"查实际加载路径,常见误改/etc/my.cnf,但 MySQL 实际读的是/etc/mysql/my.cnf或~/.my.cnf - 写错段落:必须在
[mysqld]段下写max_connections = 500,写在[client]或[mysql]下完全无效 - 语法错误导致降级:空格、等号缺失、引号、单位(如
500k)都会让 MySQL 启动时跳过该行,默默回退到默认 151 - systemd 服务限制未同步:即使配置写了 5000,若
LimitNOFILE还是 1024,MySQL 启动时会自动把max_connections截断为 ≈1024−50
永久生效的三种方式,优先级从高到低
不是“选一个就行”,而是要按顺序检查是否全部到位:
-
SET PERSIST max_connections = 500;:写入mysqld-auto.cnf,重启后仍有效;但需SYSTEM_VARIABLES_ADMIN权限,且不能超过 OS 限制或编译硬上限(默认 16384) - 配置文件修改:在
[mysqld]段添加max_connections = 500,然后systemctl restart mysqld;注意要同步改/usr/lib/systemd/system/mysqld.service中的LimitNOFILE和LimitNPROC - 启动命令覆盖:临时调试可用
mysqld --max_connections=500,但生产环境禁用——无法持久、难管理、易遗漏资源限制
验证是否真生效,别信 SHOW VARIABLES 就完事
光看 SHOW VARIABLES LIKE 'max_connections' 是假安全。必须交叉验证:
- 查进程实际打开的文件数上限:
cat /proc/$(pidof mysqld)/limits | grep "Max open files",第一列数值应 ≥ 你设的max_connections+ 50 - 确认历史峰值没被掩盖:
SHOW GLOBAL STATUS LIKE 'Max_used_connections';—— 如果这个值长期接近你设的新上限,说明不是配置没生效,而是应用连接池没控住,或有连接泄漏 - 观察错误日志:真正打满时,新连接报的不是标准
Too many connections,而是Can't create thread (errno 11)或Out of memory,那说明已触发 OS 层限制或内存耗尽
最容易被跳过的一步:线程级 buffer 必须同步压降
很多人设了 max_connections = 2000 就以为搞定,结果上线半小时 OOM。因为每个连接默认分配 sort_buffer_size、read_buffer_size 等线程级缓存,这些是独占不共享的:
- 默认
sort_buffer_size = 256K,2000 连接就吃掉 512MB;若被调成 4MB,直接干掉 8GB - 生产环境建议显式设为
sort_buffer_size = 256K、join_buffer_size = 256K、read_buffer_size = 128K - 验证方式:
SHOW VARIABLES输出里重点盯这几个值,别让它们悄悄变成2M或4194304
max_connections 的从来不是 MySQL 自身,而是你没看见的 ulimit、systemd、buffer 分配和应用连接池。配置写对只是起点,验证它在 OS 层和内存层都稳住,才算落地。











