MySQL 8.0无法真正限制单用户的CPU、内存或磁盘配额;Resource Groups仅对SELECT查询做VCPU绑定且需显式设置,写操作完全绕过;唯一原生硬限是MAX_QUERIES_PER_HOUR语句频次控制。

MySQL 8.0 中无法真正限制单用户的 CPU、内存或磁盘配额,Resource Groups 只能对部分 SELECT 查询做 CPU 绑定,且必须显式绑定、仅限 USER 类型、不控制写操作。
CREATE RESOURCE GROUP 必须带 TYPE 和 VCPU 才生效
漏掉 TYPE 或 VCPU 参数会导致资源组创建成功但完全无效:查 INFORMATION_SCHEMA.RESOURCE_GROUPS 会发现 VCPU_IDS 是 NULL 或 0-0,绑定后线程仍在默认 CPU 上跑。
-
TYPE = USER是强制项;SYSTEM类型仅供 MySQL 内部线程使用,用户线程无法绑定 -
VCPU必须是有效范围,如0、1-2、0,2,4;填-1或留空会静默失败 -
THREAD_PRIORITY在 Linux 上需 root 权限 +CAP_SYS_NICE能力才实际生效;没开能力时设了也等于没设
SET RESOURCE GROUP 只对后续 SELECT 查询起作用
执行 SET RESOURCE GROUP rg_slow 后,当前会话中**下一个 SELECT 语句开始**才会被调度到指定 VCPU,已运行中的查询不受影响,也不会中断。
- 不能靠它“实时掐断”一个正在执行的慢 SQL;真要干预,得先
KILL QUERY,再让应用重试并确保重试连接绑定了资源组 - 应用连接池复用连接频繁,
SET命令容易绑错会话;若未启用performance_schema(默认关闭),连活跃线程 ID 都查不到 - 所有写操作——
INSERT、UPDATE、DELETE、ALTER TABLE——完全绕过资源组调度,哪怕你显式绑定了线程
MAX_QUERIES_PER_HOUR 是唯一原生频率硬限,但只计数不看耗时
这是 MySQL 8.0+ 唯一支持的用户级“限流”机制,按自然小时(00:00–23:59)滚动统计语句总数,所有语句类型都算 1 次(COMMIT/ROLLBACK/SHOW 等除外)。
- 必须用
CREATE USER ... WITH MAX_QUERIES_PER_HOUR N或ALTER USER ... WITH MAX_QUERIES_PER_HOUR N设置;GRANT ... WITH已废弃,逻辑危险且易误配 - 它防不住大查询:一条
SELECT * FROM huge_table和一条SELECT SLEEP(1)都只算 1 次 - 连接池不会导致该限制失效,但效果会打折扣——因为多个请求可能复用同一连接,计数集中在少数会话上
真正需要隔离资源时,别只盯 MySQL 内置功能
MySQL 不跟踪用户级磁盘用量,也不限制内存占用。所谓“用户资源上限”,在生产中往往得靠组合手段:
- OS 层 quota 控制
/var/lib/mysql/db_app1/目录总空间,配合innodb_file_per_table=ON和独立表空间实现粗粒度磁盘约束 - 用
pt-diskusage定期扫描目录大小,超阈值自动告警或清理临时表 / binlog / undo 日志 - 长事务、GROUP BY 产生的磁盘临时表、binlog、undo 文件这些隐性空间消耗点,根本无法归因到具体用户
最常被忽略的是:Resource Groups 对写操作完全无效,而业务里真正吃 CPU 和 I/O 的,往往是 INSERT/UPDATE 批处理——它们照常跑满所有核,资源组形同虚设。


















