alter user可直接修改已有账号的max_user_connections,立即生效且无需重启;设为0表示不限(受全局max_connections约束),需确保连接池配置≤该值,否则触发error 1226。

直接改用户自身的 MAX_USER_CONNECTIONS,不是改全局变量。 SET GLOBAL max_user_connections = 5 只影响新用户的默认值,对已有账号完全无效——这是最常踩的坑。
ALTER USER 修改已有账号的连接上限
生产环境绝大多数情况用这个。执行后立即生效,无需重启 MySQL。
- 必须有
CREATE USER或ALTER USER权限 - 账号名和主机名要跟
SHOW GRANTS输出的完全一致,'app'@'localhost'和'app'@'127.0.0.1'是两个独立账号 - 设为
0表示不限(依赖全局max_connections) - 执行完建议立刻查表确认:
SELECT User, Host, max_user_connections FROM mysql.user WHERE User = 'app';
示例:ALTER USER 'app'@'192.168.1.%' WITH MAX_USER_CONNECTIONS 3;
CREATE USER 创建时就绑定限制
适合新服务上线或初始化账号阶段,避免后期补漏。
- 语法必须带
WITH MAX_USER_CONNECTIONS N,不能写成MAX_USER_CONNECTIONS = N - MySQL 5.7 不支持该语法,得用
GRANT USAGE ... WITH MAX_USER_CONNECTIONS替代 - 如果用的是 MySQL 8.0+,推荐一步到位:
CREATE USER 'api'@'%' IDENTIFIED BY 'xxx' WITH MAX_USER_CONNECTIONS 10;
为什么 SHOW PROCESSLIST 里看到的连接数还是超了
限制只在新建连接时校验,已建立的连接不会被踢出或拒绝。
- 应用没正确
close()连接,或连接池长期空闲不释放,会导致“历史连接堆积” -
wait_timeout设得太大(默认 28800 秒),僵尸连接挂着不动,真实请求反而连不上 - 验证是否真生效:用新客户端反复发起连接,而不是只看
SHOW PROCESSLIST历史快照 - 查当前活跃连接数更准:
SELECT user, host, COUNT(*) FROM information_schema.processlist GROUP BY user, host;
连接池配置和实际限制必须对齐
连接池最大值 > 用户连接上限,等于埋雷。
- HikariCP 的
maximumPoolSize、Druid 的maxActive必须 ≤ 对应账号的MAX_USER_CONNECTIONS - PHP 的 PDO 默认不复用连接,短脚本反复
new PDO()但没 unset,可能几秒内就占满配额 - Java 应用启动失败报错
ERROR 1226 (42000),大概率是连接池配置越界
真正容易被忽略的是:限制生效后,旧连接不会自动清理,必须靠应用主动断开或等 wait_timeout 触发。空闲连接不释放,新连接就被卡在门外——这不是配置没生效,而是资源没腾出来。











