alter user是mysql 5.7.6+设限唯一可靠方式,set global max_user_connections仅影响新用户默认值;create user需带with关键字才生效;查mysql.user表和实测连接超限报错error 1226验证是否生效。

ALTER USER 是唯一可靠方式(MySQL 5.7.6+)
对已有用户设限,必须用 ALTER USER,SET GLOBAL max_user_connections 完全无效——它只影响后续新建用户的默认值,不会修改任何现存账号。执行后不需 FLUSH PRIVILEGES,立即生效。
-
ALTER USER 'app_user'@'%' WITH MAX_USER_CONNECTIONS 20;中的'app_user'@'%'必须和SHOW GRANTS FOR 'app_user'@'%'输出的 Host 完全一致;'app_user'@'localhost'和'app_user'@'127.0.0.1'是两个独立账号 - 设为
0表示不限制(等同于依赖全局max_connections),不是禁止登录 - 该限制只校验新建连接,已存在的超限连接不会被中断或踢出
CREATE USER 创建时直接设限(适合新账号)
上线新服务或初始化账号时,一步到位最安全。语法里 WITH 关键字不可省略,漏写会报错或静默忽略。
- 正确写法:
CREATE USER 'api_user'@'10.20.%' IDENTIFIED BY 'xxx' WITH MAX_USER_CONNECTIONS 3; - 错误写法:
CREATE USER ... IDENTIFIED BY 'xxx' MAX_USER_CONNECTIONS 3;(缺WITH,语句不报错但限制不生效) - 创建后仍需查
mysql.user表确认,因为权限语句本身不保证持久化成功
验证是否真生效?别信命令输出,查表+实测
SHOW GRANTS 不显示 MAX_USER_CONNECTIONS,因为它不是权限,而是用户元数据属性。唯一可信路径是查表 + 超限触发。
- 查配置:
SELECT User, Host, max_user_connections FROM mysql.user WHERE User = 'app_user';—— 字段名是小写max_user_connections,不是Max_user_connections或大写变体 - 查实时连接数(需开启
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' resource limit
连接池配置必须 ≤ 用户限制值
HikariCP、Druid 等连接池默认维持 idle 连接,哪怕业务流量为零,也会立刻占满配额。超限错误不是配置失败,而是限制正在起作用。
- 若应用配置了
maximumPoolSize = 10,但数据库账号限制为MAX_USER_CONNECTIONS 5,启动或压测时必然报ERROR 1226 - 多个服务共用同一账号(如所有微服务都连
'app'@'%')时,建议按实例拆分账号,例如'app_web1'@'10.0.1.10'和'app_web2'@'10.0.1.11',再分别设限 - 空闲连接未释放(比如
wait_timeout太长)也会卡满配额,需同步检查应用close行为和连接池的idleTimeout、maxLifetime配置
SET GLOBAL max_user_connections 当成账号级开关,或者查 mysql.user 表看到 NULL 就以为没生效——其实 NULL 等价于 0(不限),而真正要命的是连接池配置比限制值还大,且没人去核对。











