max_connections可动态设置生效但重启丢失,写入my.cnf需重启;单用户连接限制通过CREATE/ALTER USER的MAX_USER_CONNECTIONS实现,按'user'@'host'独立计数。

max_connections 是全局限制,改完要重启或动态生效?
MySQL 的 max_connections 是服务级总连接数上限,不是按用户算的。它控制的是整个 mysqld 进程能接受多少并发 TCP 连接,所有用户加起来不能超这个数。
修改后不一定非要重启:
- 如果用
SET GLOBAL max_connections = 200;,立刻生效,但 MySQL 重启后会丢失(除非同步写进配置文件) - 写进
my.cnf的[mysqld]段里(如max_connections = 200),必须重启 mysqld 才生效 - 注意:动态设置时,如果当前活跃连接已接近上限,
SET GLOBAL可能被拒绝并报错ERROR 1227 (42501): Access denied—— 需要有SUPER或SYSTEM_VARIABLES_ADMIN权限
想限制单个用户的连接数,得用 CREATE USER 的 MAX_USER_CONNECTIONS
MySQL 本身不提供“每个用户最多连 N 个”的运行时策略开关,但支持在创建或修改用户时硬编码该限制,靠权限系统实现资源隔离。
实操要点:
- 新建用户时直接指定:
CREATE USER 'app_user'@'%' IDENTIFIED BY 'pwd' WITH MAX_USER_CONNECTIONS 10; - 已有用户用
ALTER USER 'app_user'@'%' WITH MAX_USER_CONNECTIONS 10; - 设为 0 表示不限制(默认值),设为正整数才启用限制
- 这个限制是「每个账号」维度的,和 host 组合唯一识别(即
'user'@'192.168.%'和'user'@'localhost'是两个独立配额) - 连接数超限时,新连接会报错:
ERROR 1226 (42000): User 'app_user' has exceeded the 'max_user_connections' resource (current value: 10)
MAX_USER_CONNECTIONS 不会自动释放,得靠客户端断开或 wait_timeout
这个限制不是“每秒最多 N 次”,而是“同时最多 N 个活跃连接”。如果应用没正确 close 连接、或连接池长期空闲不释放,很容易卡在上限不动弹。
常见陷阱:
- PHP 的
mysql_connect()(已废弃)或 PDO 默认不复用连接,短脚本反复 connect 但没unset($pdo)或$pdo = null,可能快速占满配额 - Java 应用用 HikariCP 等连接池,若
maximumPoolSize > MAX_USER_CONNECTIONS,启动阶段就可能失败 -
wait_timeout(默认 28800 秒)决定空闲连接多久被 server 主动断开;如果设得太大,僵尸连接长期挂着,真实用户反而连不上 - 查当前各用户实际连接数:
SELECT user, host, COUNT(*) FROM information_schema.processlist GROUP BY user, host;
max_connections 太小会导致 accept 队列溢出,出现 Connection refused
当 max_connections 被打满,新 TCP 握手请求会被内核丢弃,客户端看到的往往不是 MySQL 错误,而是操作系统级的 Connection refused 或超时,排查容易绕弯。
关键判断点:
- 看 MySQL 错误日志有没有
Too many connections—— 有,说明是应用层打满了 - 没有该日志但大量连接失败,用
ss -s | grep "tcp:"查看orphan或tw数量突增,可能是 SYN 队列满(net.ipv4.tcp_max_syn_backlog不足)或 accept 队列溢出(net.core.somaxconn太小) - 临时调高
max_connections只是缓解,真正要压测验证应用连接释放逻辑是否健壮 - 云数据库(如 RDS)通常限制更严,且
max_connections受实例规格硬约束,改配置前先查文档上限值
配额类限制最麻烦的不是设多少,而是谁在占、为什么不放、错误反馈是否清晰——尤其跨服务调用时,一个没关的连接可能卡住下游整个链路。


















