max_queries_per_hour 不能限制 cpu,因为它仅按语句数量计数,不考虑执行时间或资源消耗;适合防高频低害行为,而非控cpu/内存;mysql 5.7无用户级cpu配额,需用max_execution_time、cgroups或应用层优化替代。

MySQL 5.7 本身不支持按用户限制 CPU 使用率,MAX_QUERIES_PER_HOUR 也不是 CPU 限制手段,它只统计语句数量,和 CPU 消耗无直接关系。
为什么 MAX_QUERIES_PER_HOUR 不能限制 CPU
这个参数纯粹是计数器:每执行一条语句(SELECT、INSERT、UPDATE 等)就加 1,到点清零。它不管这条语句跑了 1ms 还是 10s,也不管它扫了 1 行还是 100 万行。一个低效的 SELECT 可能占满 CPU 却只算作 1 次查询;而 100 个轻量 SELECT 加起来可能才消耗 1% CPU 却已触发配额拒绝。
常见错误现象:
- 设了
MAX_QUERIES_PER_HOUR 10,但用户跑一个慢查询就把 CPU 打满,配额却没拦住 - 应用报错
User 'xxx' has exceeded the 'max_questions' resource (current value: 10),但服务器 CPU 依然很低——说明配额误伤了正常流量
MAX_QUERIES_PER_HOUR 的真实适用场景
它适合用于防“高频低害”行为,比如自动化轮询、爬虫试探、或防止脚本误写成死循环发大量空查询。不是用来控 CPU 或内存的。
使用时注意:
- 该限制对隐式查询也计数(如触发器、外键检查、元数据查询),实际触发比预期快
- 值设太小会导致 ORM 框架(如 Laravel、Django)因预编译、连接检测等额外查询频繁撞限
- 必须用
CREATE USER或ALTER USER设置,GRANT ... WITH在 5.7+ 已被标记为过时语法,部分版本会忽略 - 修改后需执行
FLUSH PRIVILEGES才生效(尤其在非 SUPER 用户下操作时)
真正想控 CPU,得换思路
MySQL 5.7 没有用户级 CPU 配额功能。可行路径只有三条:
-
用
MAX_EXECUTION_TIME拦慢查询:仅对SELECT有效,单位毫秒,需在会话或语句级设置(如SELECT /*+ MAX_EXECUTION_TIME(3000) */ * FROM t) -
靠操作系统级隔离:用
cgroups(Linux)或Windows Job Objects限制整个mysqld进程的 CPU 配额,但这是全局控制,无法区分用户 - 从应用层收敛:在连接池配置里限制最大活跃连接数 + 启用查询超时 + 对高风险 SQL 做白名单审核,比依赖数据库配额更可靠
别把 MAX_QUERIES_PER_HOUR 当 CPU 开关用——它连温度计都不是,顶多是个计步器。真要压 CPU,得去查 SHOW PROCESSLIST 找出那几个长耗时线程,再结合慢日志和执行计划优化 SQL,或者上 cgroups 划硬资源边界。











