resource group 无法限制查询频次,仅支持 cpu 和内存配额;应使用 user account limits(5.7.21+/8.0.3+)设置每小时 select/update 等语句总数限制,按自然小时重置,不区分 sql 内容,也不限制并发。

MySQL 8.0+ 中用 RESOURCE GROUP 无法实现查询频次限制
RESOURCE GROUP 只能限制 CPU、内存等资源配额,不支持按小时计数的查询/更新频次控制。想靠它限速 SELECT 或 UPDATE 次数,直接失败。
真正可行的方式:用 MySQL 的 USER ACCOUNT LIMITS(5.7.21+ / 8.0.3+)
MySQL 原生支持对用户设置每小时最大语句执行次数,但注意:它按“语句类型”统计,且只对 SELECT、UPDATE、INSERT、DELETE 四类生效,不区分具体 SQL 内容或 WHERE 条件。
- 创建用户时直接指定:
CREATE USER 'api_user'@'%' WITH MAX_QUERIES_PER_HOUR 120 MAX_UPDATES_PER_HOUR 30;
- 已有用户用
ALTER USER修改:ALTER USER 'api_user'@'%' WITH MAX_QUERIES_PER_HOUR 60 MAX_UPDATES_PER_HOUR 15;
- 设为 0 表示不限制;设为 1 表示每小时最多执行 1 次该类型语句
- 计时窗口是自然小时(从整点开始),不是滑动窗口,比如 13:59 执行第 120 次
SELECT,14:00 后重置计数
常见错误:误以为 max_questions 和 max_updates 是“每秒”或“并发”限制
MAX_QUERIES_PER_HOUR 和 MAX_UPDATES_PER_HOUR 是累计计数器,跟并发无关。哪怕你瞬间发 100 个 SELECT,只要在一小时内没超总数,就全放行——它不拦并发,只拦总量。
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
- 如果你实际要防突发流量,这机制不够用,得在应用层加令牌桶或漏桶
- 错误日志里出现
Too many connections?那是max_connections配置问题,和这个 hourly limit 无关 - 用户执行存储过程时,内部的
SELECT不计入调用者的MAX_QUERIES_PER_HOUR,只算最外层语句
低版本 MySQL(
5.7.20 及更早版本不支持 WITH MAX_XXX_PER_HOUR 语法,硬上只能靠中间件或代理层拦截:
- ProxySQL 支持基于用户+时间窗口的 query rule + rate limiting,配置项是
mysql-query_rules表里的apply_rate_limit - 应用层记录用户 IP + 时间戳 + SQL 类型到 Redis,每次查询前
INCR并EXPIRE3600 秒,超阈值就拒绝 - 不要试图用触发器或审计插件做实时计数——开销大、易出错、不原子
真正上线前务必验证:用 SHOW GRANTS FOR 'user'@'%' 确认 limits 已生效,再用脚本循环执行 SELECT 1 触发限流,观察是否返回 ERROR 1226 (42000): User 'xxx' has exceeded the 'max_questions' resource。










