修改 max_connections 不生效,需确认 mysql 实际加载的配置文件路径、确保修改在 [mysqld] 段内、同步调整系统级 ulimit 和 wait_timeout,并根据内存合理设置连接数与 thread_cache_size。

直接改 max_connections 不生效,八成是系统级限制或配置文件没落对地方。
确认 MySQL 实际加载的 my.cnf 路径
宝塔、一键包、源码编译安装的 MySQL 加载配置顺序不一致,改错文件等于白改。常见陷阱是:你在宝塔面板点“配置修改”保存了,但 MySQL 启动时读的是 /etc/my.cnf,而你改的是 /www/server/mysql/etc/my.cnf。
执行这条命令看真实加载路径:mysql --help | grep "Default options"
或者查错误日志:grep "my.cnf" /www/server/data/*.err(宝塔环境)
MySQL 8.0+ 还可运行:SELECT @@global.config_file;
- 只在被真正读取的文件中修改,且必须放在
[mysqld]段内 - 别加在
[client]或段外,也别写在注释里 - 改完必须
systemctl restart mysqld,仅重载配置(reload)不生效
同步放开 Linux 系统级文件描述符限制
MySQL 每个连接对应一个 socket 文件描述符。如果系统默认 ulimit -n 是 1024,哪怕你设了 max_connections = 10000,MySQL 启动时就会报 Can't start server: Bind on TCP/IP port. Got error: 24: Too many open files,甚至直接拒绝启动。
分两步做:
- 编辑
/etc/security/limits.conf,末尾加两行:mysql soft nofile 65535mysql hard nofile 65535 - 如果是 systemd 管理(主流发行版默认),还要在
/etc/systemd/system/mysqld.service.d/override.conf里加:[Service]LimitNOFILE=65535 - 改完必须重启
mysqld进程,systemctl daemon-reload不够
别只盯着 max_connections,先看 wait_timeout 和连接池
很多“连不上”的问题根本不是上限低,而是连接堆积在 Sleep 状态没释放。比如 PHP-FPM 开了 100 个子进程,每个都用 mysql_pconnect 建了长连接,wait_timeout 又是默认的 28800 秒(8 小时),那这 100 个连接就永远占着 slot,新请求全卡住。
- 线上建议把
wait_timeout和interactive_timeout都设为300(5 分钟)或600(10 分钟) - PHP 应用别滥用持久连接,优先用 PDO + 连接池(如 Swoole 的
mysql->getConn()或 Laravel 的DB::connection()->reconnect()) - Java 项目必须配
HikariCP的maxLifetime和idleTimeout,否则连接池会把过期连接继续塞给 MySQL - 查真实压力:
SHOW STATUS LIKE 'Threads_connected';和SHOW STATUS LIKE 'Max_used_connections';,后者接近max_connections才真要调
max_connections 设多大才算合理?看内存和 thread_cache_size
每个 MySQL 连接线程默认吃掉 256KB–1MB 内存(取决于 sort_buffer_size、read_buffer_size 等会话级参数)。设太高,内存先爆,MySQL 直接 OOM kill。
- 2GB 内存服务器,
max_connections别超120;4GB 可到300;8GB 建议500–800 - 配套调
thread_cache_size,公式参考:8 + max_connections / 100(比如 500 连接设为 12–16) - 别盲目拉高
innodb_buffer_pool_size,它和连接数抢内存。8GB 总内存机器,设innodb_buffer_pool_size = 4G+max_connections = 600已逼近极限
最常被忽略的其实是连接空闲时间——wait_timeout 不调,max_connections 再大也撑不过一次流量尖峰后的连接滞留。











