set global max_user_connections对已有用户完全无效,它仅设定新用户的默认值;真正生效的是mysql.user表中各账号独立的max_user_connections字段,需用alter user显式设置并验证。

SET GLOBAL max_user_connections 对已有用户完全无效——它只影响后续新创建用户的默认值,不是控制现有账号的开关。
为什么 SET GLOBAL max_user_connections 不起作用
执行这条命令后,app_user 的连接数照样能飙到上百。真正起效的是每个账号在 mysql.user 表中独立存储的 max_user_connections 字段(注意全小写、下划线),MySQL 在新建连接时只查这个字段。
- 你改了
max_user_connections全局值,但SELECT User, Host, max_user_connections FROM mysql.user WHERE User = 'app_user'返回仍是NULL或旧数字 -
SHOW VARIABLES LIKE 'max_user_connections'显示 10,不代表app_user被限了 10,它只是“下一个CREATE USER默认用 10” - 压测时仍触发
ERROR 1226,说明限制没落地——问题不在全局变量,而在用户记录本身
正确做法:用 ALTER USER 显式修改用户字段
MySQL 5.7.6+ 必须用 ALTER USER 修改已有用户,且 Host 必须和 SHOW GRANTS FOR 'app_user'@'host' 输出完全一致:
-
app_user@'%'和app_user@'localhost'是两个账号,要分别设 - 语法必须带
WITH关键字:ALTER USER 'app_user'@'%' WITH MAX_USER_CONNECTIONS 8 - 设为
0表示不限(等同于未设置),不是禁止连接;设为1才真只允许 1 个活跃连接 - 修改后立即生效,无需
FLUSH PRIVILEGES
验证是否真生效,不能只看 mysql.user 表
SELECT 出来是 8,不代表运行时拦截有效。必须实测新建连接:
- 查实时活跃连接:
SELECT user, COUNT(*) FROM performance_schema.threads WHERE TYPE = 'FOREGROUND' AND user = 'app_user' - 开多个终端,并发执行:
mysql -u app_user -p -e "SELECT 1;" - 第
N+1次(N是你设的上限)应明确报错:ERROR 1226 (42000): User 'app_user' has exceeded the 'max_user_connections' resource -
SHOW PROCESSLIST看到的连接数超限?正常——旧连接不会被踢,限制只在校验新建连接时触发
连接池配置必须 ≤ 用户限制值
这是最容易被忽略的落地环节:
- HikariCP 的
maximumPoolSize、Druid 的maxActive,必须 ≤ 对应账号的MAX_USER_CONNECTIONS值 - 多个微服务共用同一账号(如
app@'%'),各自配了 20,总连接数轻松突破 100 - 空闲连接未释放(
wait_timeout过长或连接池 idle 配置不合理)也会卡满配额
mysql.user 表里的那个具体数值;而应用能否撑住这个限制,取决于连接池有没有同步调低。











