<p>必须用 GRANT USAGE ON . TO 'u'@'h' WITH MAX_CONNECTIONS_PER_HOUR N 设置,ALTER USER 不支持该参数;需 FLUSH PRIVILEGES,验证查 mysql.user 表 max_connections 字段。</p>

直接结论:用 GRANT USAGE 配合 WITH MAX_CONNECTIONS_PER_HOUR N 设置,不是 ALTER USER,也不是改配置文件或系统变量。
为什么 ALTER USER 'u'@'h' WITH MAX_CONNECTIONS_PER_HOUR N 会报错
MySQL 不允许用 ALTER USER 修改 MAX_CONNECTIONS_PER_HOUR —— 这是硬性语法限制(至少到 8.4 仍如此)。官方文档明确要求必须通过 GRANT USAGE 重赋权。常见错误包括:
- 误写成
ALTER USER 'u'@'h' WITH MAX_CONNECTIONS_PER_HOUR 60→ 报错ERROR 1064 (42000) - 漏掉
USAGE,只写GRANT ON *.* TO 'u'@'h' WITH MAX_CONNECTIONS_PER_HOUR 60→ 语法不合法 - 省略主机名,如
'u'@''或'u'→ MySQL 拒绝解析,权限不生效
正确设置的三步实操流程
对已有用户(比如 'app_user'@'%')设每小时最多 120 次新连接:
- 执行
GRANT USAGE ON *.* TO 'app_user'@'%' WITH MAX_CONNECTIONS_PER_HOUR 120 - 必须显式运行
FLUSH PRIVILEGES(MySQL 8.0.16+ 虽部分场景自动刷新,但生产环境务必手动执行) - 验证是否写入成功:
SELECT User, Host, max_connections FROM mysql.user WHERE User = 'app_user'—— 注意字段名是max_connections,不是max_connections_per_hour或max_user_connections
设了却没拦住连接?先排查这四点
现象:明明设了 MAX_CONNECTIONS_PER_HOUR 30,但脚本一小时连了 200 次也没报错。原因往往不在参数本身:
- 应用用了连接池(如 HikariCP),实际只建立 1~2 个物理连接,反复复用 ——
MAX_CONNECTIONS_PER_HOUR只统计mysql_real_connect()成功次数,不统计语句执行 - MySQL 版本低于 5.6.3(该功能从 5.6.3 引入),旧版本会静默忽略该参数
- 用户通过 ProxySQL / MaxScale 等代理连接,代理以固定后端账号连 MySQL,真实客户端的账号/主机信息未透传,MySQL 实际看到的是代理账号
- 误在
CREATE USER时写成CREATE USER 'u'@'h' IDENTIFIED BY 'p' MAX_CONNECTIONS_PER_HOUR 30(漏WITH)→ 语法无效,被跳过
和 max_user_connections、max_connections 的关键区别
这三个名字像,但完全不相干,别混用:
-
max_connections(全局变量):整个 MySQL 实例允许的最大并发连接数,由SET GLOBAL max_connections = N控制 -
max_user_connections(用户级字段):该用户「当前最多几个活跃连接」,超了就拒绝新连接,报错Too many connections -
max_connections(mysql.user表字段,对应MAX_CONNECTIONS_PER_HOUR):该用户「每小时最多新建几次连接」,超了报错ERROR 1226 (42000)
最容易被忽略的是:连接池复用会让 MAX_CONNECTIONS_PER_HOUR 形同虚设,而 max_user_connections 才真正卡住并发数 —— 如果你真想防爆连,这两个得一起配,且调低 wait_timeout 防 Sleep 连接堆积。


















