MySQL 8.0 资源组仅对 SELECT 线程做 CPU 亲和性绑定和调度优先级干预,DML 完全不受控;创建 TYPE=USER 资源组必须指定真实 VCPU 和 THREAD_PRIORITY,否则无效;SET RESOURCE GROUP 仅对后续新 SELECT 语句生效,且不解决锁、内存、I/O 或 CPU 配额问题。

MySQL 8.0 的资源组无法真正“隔离负载”,它只对 SELECT 查询线程做 CPU 亲和性绑定和调度优先级干预,且 DML(INSERT/UPDATE/DELETE)完全不受控。 想靠 CREATE RESOURCE GROUP 实现 OLTP 和报表的资源硬隔离,会踩进多个设计边界里——先说清楚这点,再给可落地的操作路径。
创建 TYPE=USER 资源组必须带真实 VCPU 和 THREAD_PRIORITY
漏掉任一关键参数,资源组就只是个空壳。查 INFORMATION_SCHEMA.RESOURCE_GROUPS 时若 VCPU_IDS 是 NULL 或 0-0,说明没生效。
-
TYPE = USER是强制项;TYPE = SYSTEM只供 MySQL 内部线程用,你绑不了 -
VCPU必须填服务器真实存在的逻辑 CPU ID:8 核机器是0-7,写VCPU = 4-7有效,写VCPU = "0-3"(带引号)或VCPU = 8-15直接失效 - 支持三种格式:
0(单核)、2-5(连续)、0,2,4(离散),不能混用、不能越界、不能留空 -
THREAD_PRIORITY范围是 -20(最高)到 19(最低),OLTP 组建议设-10,报表组设10,但注意:这只是影响内核调度顺序,不是 CPU 使用率限制 - 务必预留至少 1–2 个核给系统线程(如
SYS_default),否则 mysqld 自身可能卡死在metadata lock或 purge 上
SET RESOURCE GROUP 只对后续新语句生效,且仅限 SELECT
这是最常被误用的点。执行 SET RESOURCE GROUP oltp_high_priority 后,当前正在跑的那条慢查询不会暂停、不会迁移、也不会降优先级——它继续在原 CPU 上跑完。只有下一条语句才受约束。
- 资源组只对
SELECT、INSERT、UPDATE、DELETE、REPLACE、DO生效;CREATE TABLE、SHOW、ALTER TABLE等 DDL 和管理命令完全无视 - 写操作类语句(
INSERT/UPDATE/DELETE)完全绕过资源组调度逻辑,实测如此,文档未明说但行为确定 - 若想让某条报表查询走低优先级组,必须在执行前显式声明:
SET RESOURCE GROUP batch_low_priority; SELECT ...; - 连接池(如 HikariCP)复用连接时,
THREAD_ID频繁变化,临时SET容易绑错会话;建议优先用用户级绑定:ALTER USER 'report_user'@'%' RESOURCE GROUP = batch_low_priority;
权限、配置与静默失败排查
三个常见原因会导致 SET RESOURCE GROUP 执行后毫无效果:
- 用户缺少
RESOURCE_GROUP_ADMIN权限:必须显式授权GRANT RESOURCE_GROUP_ADMIN ON *.* TO 'app_user'@'%'; - MySQL 启动时未启用资源组:检查
SELECT * FROM performance_schema.setup_actors;中RESOURCE_GROUP列是否为ENABLED;若否,需在配置文件加resource_group_enabled=ON并重启 - 静默失败:当指定的
VCPU范围超出系统实际 CPU 数(如设VCPU=4-7但机器只有 4 核),MySQL 不报错,但组不可用;查performance_schema.resource_groups表,看ACTIVE_THREADS是否始终为0 - 应用层未重置:使用连接池时,
SET RESOURCE GROUP可能被复用连接覆盖;建议每次执行前重置:SET RESOURCE GROUP ; SELECT ;放在同一请求内
真正复杂的是:资源组不解决锁竞争、不控制内存占用、不干预 I/O 调度,更不提供 CPU 使用率配额。它只是把 SELECT 线程尽量“钉”在某些核上,并告诉内核“这个线程可以晚点调度”。如果你的 OLTP 和报表共用同一张大表、又都走全表扫描,VCPU 绑定反而可能加剧核间争抢——这时候该调的其实是索引、事务隔离级别或查询拆分策略。


















