ALTER USER是唯一有效方式,SET GLOBAL和GRANT对已有用户均无效;必须精确匹配User@Host、查mysql.user表验证、实测触发ERROR 1226,并确保连接池配置≤限制值。

直接用 ALTER USER 设置 MAX_USER_CONNECTIONS 是唯一可靠方式,SET GLOBAL max_user_connections 对已有用户完全无效,改了也白改。
ALTER USER 是唯一生效的命令(MySQL 5.7.6+)
对已存在的账号加限制,必须走 ALTER USER。它直接更新 mysql.user 表里的 max_user_connections 字段,立即生效,不需 FLUSH PRIVILEGES,也不重启 MySQL。
-
ALTER USER 'app_user'@'%' WITH MAX_USER_CONNECTIONS 10;中的'app_user'@'%'必须和SHOW GRANTS FOR 'app_user'@'%'输出的 host 完全一致 -
'app_user'@'localhost'和'app_user'@'127.0.0.1'是两个独立账号,得分别执行 - 设为
0表示不限制(退回到全局max_connections约束),不是“禁止登录” - 设为
1就真只允许 1 个活跃连接,第 2 次新建连接会立刻报错:ERROR 1226 (42000): User 'app_user' has exceeded the 'max_user_connections' resource
为什么 GRANT 或 SET GLOBAL 都不靠谱
GRANT ... WITH MAX_USER_CONNECTIONS 只在创建新用户时有效;对已有用户执行,语句不报错但限制不写入表。而 SET GLOBAL max_user_connections = N 更是陷阱——它只影响后续新创建用户的默认值,不会动任何现存账号的字段。
- 执行
SET GLOBAL max_user_connections = 5;后查mysql.user,目标用户的max_user_connections字段仍是NULL或旧值 - 压测时突然爆出
ERROR 1226,往往就是误信了这个“全局设置” - MySQL 8.0+ 的系统表字段名是小写
max_user_connections,不是Max_user_connections或驼峰写法
验证是否真生效?别信命令输出,查表 + 实测
配置写进去了,不代表连接池或客户端会守规矩。唯一可信路径是两步:确认字段值、触发超限错误。
- 查配置:
SELECT User, Host, max_user_connections FROM mysql.user WHERE User = 'app_user';—— 返回值必须是你设的数字,不能是NULL或0 - 查实时连接(需开启
performance_schema):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
连接池配置必须 ≤ 用户限制值
这是最容易被忽略的落地环节。HikariCP 的 maximumPoolSize、Druid 的 maxActive 等参数,必须 ≤ 数据库账号的 MAX_USER_CONNECTIONS 值。
- 若应用配了
maximumPoolSize = 20,但数据库账号限制为5,启动或首次压测就必然失败 - 连接池不会自动降级或重试,日志里反复出现
ERROR 1226就是它在拼命连却总被拒 - 多个微服务共用同一账号(如
'app'@'%'),各自连接池都配了 20,总连接数轻松突破 100,限制形同虚设
真正难的不是执行那条 ALTER USER,而是把账号按 host 拆清楚、把连接池配对、再用真实连接去撞一次 ERROR 1226 —— 不撞一下,永远不知道哪边没对齐。


















