alter user 设置 max_user_connections 是唯一可靠且立即生效的方式;set global 无效,create user 时需用 with 关键字绑定限制,验证须查 mysql.user 表并实测连接。

直接用 ALTER USER 设置 MAX_USER_CONNECTIONS,是唯一可靠、立即生效的手段;SET GLOBAL max_user_connections 对已有用户完全无效,别被名字误导。
ALTER USER 修改已有用户连接上限
生产环境绝大多数情况是给已存在的账号加限制,ALTER USER 是唯一推荐方式。它不改权限、密码或 SSL 配置,只动连接数,且修改后立刻生效,MySQL 5.7.6+ 无需 FLUSH PRIVILEGES。
-
ALTER USER 'app_user'@'%' WITH MAX_USER_CONNECTIONS 8;—— 执行完马上起效 - 必须精确匹配 host:
'app_user'@'192.168.1.%'和'app_user'@'localhost'是两条独立记录,得分别执行 - 设为
0表示不限制(退回到全局max_connections约束),线上账号不建议留0
CREATE USER 创建新用户时绑定限制
新账号务必在创建阶段就定死连接上限,避免后期疏漏。MySQL 版本差异直接影响写法:
- MySQL 8.0+(推荐):
CREATE USER 'api_user'@'%' IDENTIFIED BY 'xxx' WITH MAX_USER_CONNECTIONS 20; - MySQL 5.7:
GRANT USAGE ON *.* TO 'api_user'@'%' WITH MAX_USER_CONNECTIONS 20;(USAGE不授任何权限,只设资源限制) - 别写
CREATE USER ... MAX_USER_CONNECTIONS 20(漏WITH关键字),语句可能不报错但限制不生效
验证是否真生效,不能只看命令输出
SHOW GRANTS 根本不显示 MAX_USER_CONNECTIONS,因为它不是权限,而是用户元数据属性。唯一可信路径是查表 + 实测新建连接:
- 查配置是否写入:
SELECT User, Host, max_user_connections FROM mysql.user WHERE User = 'app_user';—— 返回值必须是你设的数字,不是0或NULL - 查当前活跃连接数(需开启
performance_schema):SELECT user, COUNT(*) FROM performance_schema.threads WHERE TYPE = 'FOREGROUND' AND user = 'app_user' GROUP BY user; - 实测触发:
mysql -u app_user -p -e "SELECT 1;"并发开第 N+1 次(N 是你设的上限),应明确报错:ERROR 1226 (42000): User 'app_user' has exceeded the 'max_user_connections'
连接池配置必须 ≤ 用户连接上限
这是最容易被忽略的落地环节:HikariCP 的 maximumPoolSize、Druid 的 maxActive 等参数,必须 ≤ 对应账号的 MAX_USER_CONNECTIONS 值。
- 否则应用启动或首次压测就会失败,错误日志里反复出现
ERROR 1226,连接池不会自动降级或重试 - 多个微服务共用同一账号(如
'app'@'%')时,总连接数会叠加突破限制——建议按实例拆分账号,例如'app_web1'@'10.0.1.10'和'app_web2'@'10.0.1.11',再分别设限 - 空闲连接未释放(比如
wait_timeout过长或连接池 idle 配置不合理),也会持续占着名额,导致新连接无法建立
真正起作用的是新建连接那一刻的校验,已建立的连接不会被中断。所以看到 SHOW PROCESSLIST 里连接数超了,不等于限制失效——得看新连接能不能建成功。











