必须用alter user显式设置max_user_connections,set global max_user_connections对已有用户完全无效;该限制只校验新建连接,设为0表示不限制,需查mysql.user表验证且连接池配置不得超过该值。

必须用 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;—— host 必须和SHOW GRANTS FOR 'app_user'@'%'输出的完全一致 -
'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
验证是否真生效,不能只看 SHOW PROCESSLIST
SHOW PROCESSLIST 显示的是当前已建立的连接,而 MAX_USER_CONNECTIONS 只在校验**新建连接**时触发。旧连接不会被踢,所以看到超限数量不等于配置失效。
- 查配置是否写入:
SELECT User, Host, max_user_connections FROM mysql.user WHERE User = 'app_user';—— 返回值必须是你设的数字,不是NULL或0 - 查真实活跃连接数:
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 是你设的上限)应直接报错ER_USER_LIMIT_REACHED
连接池配置必须 ≤ 用户限制值
应用层若用 HikariCP、Druid 等连接池,其 maximumPoolSize(或等效参数)必须 ≤ 对应账号的 MAX_USER_CONNECTIONS 值。否则启动或压测时必然失败,且连接池不会自动降级或重试。
- 常见踩坑:多个微服务共用同一账号(如
'app'@'%'),各自连接池都配了 20,总连接数轻松突破 100 - 空闲连接未释放(比如
wait_timeout太长)也会卡满配额,需同步检查应用close()行为和连接池idle_timeout配置 - MySQL 8.0+ 的
mysql.user表字段名仍是max_user_connections(小写+下划线),不是大写或驼峰
旧版本(MySQL 5.6 及更早)只能手动改系统表
低于 5.7.6 的版本不支持 WITH MAX_USER_CONNECTIONS 语法,必须走底层操作:
UPDATE mysql.user SET max_user_connections = 15 WHERE User = 'app_user' AND Host = '%';- 执行后必须
FLUSH PRIVILEGES;,否则修改不生效 - MySQL 8.0+ 已移除该字段,此法会报错
Unknown column 'max_user_connections' in 'field list' - MySQL 5.7 中,
CREATE USER不支持直接带WITH MAX_USER_CONNECTIONS,得用GRANT USAGE ON *.* TO 'user'@'host' WITH MAX_USER_CONNECTIONS 20;
真正容易被忽略的是:限制生效后,旧连接不会自动清理;空闲连接长期挂着,新连接就被卡在门外——这不是配置没起作用,而是资源没腾出来。











