mysql max_connections配置失效主因是配置未被读取或受系统级限制:先用show variables like 'config_file'确认真实配置路径及[mysqld]段设置;再检查systemd的limitnofile和limitnproc是否足够;最后验证open_files_limit是否成为瓶颈,同时注意内存与wait_timeout更易引发连接堆积。

配置写对了但没被 MySQL 读到
你改的 my.cnf 很可能根本不是 MySQL 启动时加载的那个文件。Ubuntu/Debian 默认优先读 /etc/mysql/mysql.conf.d/mysqld.cnf,CentOS 可能用 /etc/my.cnf 或 /etc/my.cnf.d/server.cnf,而如果你启动时加了 --defaults-file,那所有默认路径都作废。
直接登录 MySQL 执行:SHOW VARIABLES LIKE 'config_file'; —— 它返回的路径才是真实生效的配置文件。打开那个文件,确认 max_connections 是写在 [mysqld] 段里,而不是 [client] 或文件开头无 section 的位置。
还可以用命令验证语法是否被识别:mysqld --defaults-file=/path/to/your.cnf --verbose --help | grep max_connections。如果没输出,说明配置被跳过(常见于括号不匹配、等号前后有空格、引号没闭合)。
systemd 的 LimitNOFILE 拦住了连接数上限
MySQL 每个连接至少占 1 个文件描述符,max_connections 实际生效值 = min(配置值, open_files_limit - 预留数)。而 open_files_limit 又受 systemd 的 LimitNOFILE 控制——/etc/security/limits.conf 在 systemd 环境下对 mysqld 进程完全无效。
- 查当前限制:
cat /proc/$(pidof mysqld)/limits | grep "Max open files" - 查服务单元文件位置:
systemctl cat mysqld或systemctl cat mysql - 编辑对应文件(如
/lib/systemd/system/mysqld.service),在[Service]段下加两行:LimitNOFILE=65535LimitNPROC=65535 - 必须执行:
systemctl daemon-reload && systemctl restart mysqld(只restart不会重载 limit)
open_files_limit 被显式设小或系统 ulimit 太低
SHOW VARIABLES LIKE 'open_files_limit'; 返回值如果只有 1024 或 4096,哪怕 max_connections 设成 10000,实际最多也只能开 200–300 个连接(预留线程、日志、表缓存要吃掉几百个 fd)。
这个值由三者共同决定:systemd 的 LimitNOFILE、MySQL 配置里的 open_files_limit(如果显式写了,且比系统 limit 小,就按它来)、以及内核级 /proc/sys/fs/file-max。常见坑是配置里写了 open_files_limit = 1024,结果成了硬上限。
检查系统级限制:ulimit -n(当前 shell 值,仅作参考);真正要看的是 mysqld 进程的:cat /proc/$(pidof mysqld)/limits | grep "Max open files"。
内存和 wait_timeout 比 max_connections 更容易成为瓶颈
设高 max_connections 不等于提升吞吐,反而可能拖慢响应:每个连接默认消耗 256KB–1MB 内存,1000 连接 ≈ 多吃 256MB–1GB 常驻内存;线程切换、锁竞争、查询排队开销会陡增。
更大概率的问题是大量 Sleep 连接堆积(SHOW PROCESSLIST 里 State = 'Sleep' 且 Time > 300),根源通常是 wait_timeout 太大(默认 28800 秒)。调小它(比如设为 300)能让空闲连接更快释放,比盲目调高 max_connections 有效得多。
另外注意:应用层连接池(如 HikariCP)的 maximumPoolSize 必须小于 MySQL 的 max_connections,否则池子抢光所有连接,其他服务直接连不上。











