mysql 8.0 资源组仅支持对 select 查询线程做 cpu 亲和性绑定与优先级干预,不支持用户级 cpu 配额,且对写操作完全无效;必须显式创建 type=user 的资源组并指定真实 vcpu id,绑定后仅影响后续查询。

MySQL 8.0 的资源组不能限制特定用户的 CPU 消耗,它不支持用户级 CPU 配额,也不能控制 CPU 使用率;唯一可行的路径是:对特定 SELECT 查询线程做 CPU 亲和性绑定 + 调度优先级干预,且必须显式绑定、仅限读操作、无法覆盖写语句。
CREATE RESOURCE GROUP 必须带 TYPE 和 VCPU 才真正生效
漏掉任一关键参数,资源组就只是个空壳:查 INFORMATION_SCHEMA.RESOURCE_GROUPS 会发现 VCPU_IDS 是 NULL 或 0-0,绑给线程后毫无隔离效果。
-
TYPE = USER是强制项,用户线程只能用USER类型;SYSTEM类型仅供 MySQL 内部线程(如io_thread)使用,你无法绑定 -
VCPU必须填服务器真实存在的逻辑 CPU ID,例如 8 核机器 ID 是0–7,写VCPU = 4-7有效,写VCPU = 8-15或"0-3"(带引号)直接报错或失效 - 支持三种格式:
0(单核)、2-5(连续)、0,2,4(离散),不能混用、不能留空、不能越界 - 务必预留至少 1–2 个核给系统线程(如
SYS_default),否则 MySQL 自身可能卡死在metadata lock或purge上
SET RESOURCE GROUP FOR thread_id 只影响后续查询,不中断当前执行
这是最常被误用的点:执行 SET RESOURCE GROUP slow_sql FOR 12345 后,线程 ID 12345 正在跑的那条慢 SQL 不会暂停、不会迁移、也不会降优先级——它继续在原 CPU 上跑完。只有下一条语句才受新资源组约束。
- 查线程 ID 要用
performance_schema.threads.THREAD_ID,不是PROCESSLIST_ID;且需确保performance_schema已启用(默认关闭) - 目标线程状态不能是
Sleep,否则报错ERROR 3661 (HY000);也不能处于Waiting for table metadata lock等不可中断状态 - 若想立即生效,必须先
KILL QUERY 12345,再让应用重试,并确保重试连接已绑定资源组(比如通过ALTER USER ... RESOURCE GROUP) - 连接池复用连接时,
THREAD_ID频繁变化,临时SET很容易绑错会话,建议优先用用户级绑定而非运行时绑定
资源组只对 SELECT 生效,INSERT/UPDATE/DELETE 完全无视
这是硬限制,文档没明说但实测如此:哪怕你把 UPDATE 语句所在的线程绑到低优先级资源组,它仍会在所有 CPU 上自由调度,CPU 占用不受控。MySQL 8.0 的资源组仅作用于优化器选中的 SELECT 查询路径。
- 写操作类语句(
INSERT、UPDATE、DELETE、ALTER TABLE)完全绕过资源组调度逻辑 - 存储过程、触发器、事件中无法动态调用
SET RESOURCE GROUP,只能由客户端或 DBA 在会话层主动干预 - 想验证是否生效,只测
SELECT SLEEP(10)这类纯读语句,别拿UPDATE WHERE去试 - 如果负载以写为主,资源组基本无效;此时应转向
MAX_UPDATES_PER_HOUR或外部cgroups
真正需要隔离用户级资源时,别只盯 MySQL 内置功能:资源组本质是操作系统级调度提示,不是 MySQL 自己做时间片切分;它不跟踪内存、不监控磁盘、不统计 IO,所谓“限制用户 CPU 消耗”,在生产中往往得靠组合手段——比如 OS 层 cgroups 控制 mysqld 进程整体 CPU 配额,再配合 MAX_QUERIES_PER_HOUR 做请求密度兜底。











