MySQL中MAX_USER_CONNECTIONS必须显式设置,CREATE/ALTER USER需带WITH子句;设为0表示不限制,1则仅允1个并发连接;校验仅在新建连接时触发,已存连接不计入实时限制;与MAX_CONNECTIONS_PER_HOUR无关,后者控制每小时新建连接数。

CREATE USER 或 ALTER USER 里必须显式写 MAX_USER_CONNECTIONS
MySQL 不会从全局变量继承单用户连接限制,SET GLOBAL max_user_connections = 5 这类操作只影响新创建用户的默认值,对已有用户完全无效。真正起作用的,是每个账号在 mysql.user 表里独立存储的 max_user_connections 字段值。
建新用户时直接带上参数最稳妥:
CREATE USER 'api_user'@'%' IDENTIFIED BY 'secret123' WITH MAX_USER_CONNECTIONS 8;
已有用户改限制,用 ALTER USER:
ALTER USER 'api_user'@'%' WITH MAX_USER_CONNECTIONS 4;
- 设为
0表示不限制(依赖全局max_connections),不是禁止登录 - 设为
1就真只能维持 1 个活跃连接,第 2 次 connect 会报错ER_USER_LIMIT_REACHED - MySQL 5.7 支持该语法,但部分旧补丁版本可能要求后续执行
FLUSH PRIVILEGES;8.0+ 无需刷新
SHOW PROCESSLIST 显示超限?别急着怀疑配置没生效
常见现象:设了 MAX_USER_CONNECTIONS 3,但 SHOW PROCESSLIST 里看到这个用户有 6 个连接。这不是配置失效,而是校验时机问题——MySQL 只在新建连接握手阶段检查限制,已建立的连接不受影响。
真实原因往往来自应用侧:
- 应用没调
close()或连接池未启用空闲连接回收 - 连接处于
Sleep状态但未超wait_timeout,仍被计入配额 - 连接异常中断后未被及时清理(如网络闪断、客户端崩溃)
验证是否真生效,得用新连接实测:开多个终端,依次执行 mysql -u api_user -p -e "SELECT 1;",第 N+1 次(N 是你设的上限)应该直接失败并提示 Too many connections for user。
MAX_USER_CONNECTIONS 和 MAX_CONNECTIONS_PER_HOUR 完全不是一回事
这两个参数名字像,但控制维度完全不同,混用会导致预期外行为。
-
MAX_USER_CONNECTIONS:控制“当前时刻最多几个并发连接”,是硬性上限 -
MAX_CONNECTIONS_PER_HOUR:控制“每小时最多新建几次连接”,用于防暴力试探或频控,不影响已连状态
比如这样写是错的:
ALTER USER 'reporter'@'%' WITH MAX_CONNECTIONS_PER_HOUR 10;
它不会限制并发数,只会让该用户每小时最多成功 connect 10 次。要压并发,必须用 MAX_USER_CONNECTIONS。
低版本 MySQL 5.6 及更早不支持 WITH MAX_USER_CONNECTIONS
如果你卡在 MySQL 5.6,CREATE USER ... WITH 语法会报错。此时只能退回到老方式:先 GRANT 创建用户(或确保用户存在),再手动更新 mysql.user 表。
例如:
UPDATE mysql.user SET max_user_connections = 2 WHERE User = 'legacy_app' AND Host = '%';<br>FLUSH PRIVILEGES;
注意:GRANT 本身不写入 max_user_connections,必须显式 UPDATE。这种方式风险高,容易误操作其他字段,生产环境慎用。能升级到 5.7+ 就别硬扛。
另外,max_user_connections 是账户级配额,跟客户端 IP、进程 ID 都无关——只要是同一个 User@Host,所有连接都累计计数。这点常被忽略,尤其当应用部署在多台机器、共用一个数据库账号时。











