mysql 8.0 资源组无法限制cpu使用率,仅支持cpu亲和性绑定与调度优先级干预;必须指定type=user和真实vcpu范围才生效;set resource group仅对后续select语句生效,dml完全无视。

MySQL 8.0 无法限制用户 CPU 使用率——资源组(Resource Groups)不提供 CPU 时间配额或百分比限制,只做 CPU 亲和性绑定与调度优先级干预。试图用它“把某个用户 CPU 压到 30%”注定失败。
CREATE RESOURCE GROUP 必须带 TYPE 和 VCPU 才真正生效
漏掉任一关键参数,资源组就只是个空壳:查 INFORMATION_SCHEMA.RESOURCE_GROUPS 会发现 VCPU 字段是 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),否则 mysqld 自身可能卡死在 metadata lock 或 purge 上
SET RESOURCE GROUP FOR thread_id 只影响后续查询
这是最常被误用的点:执行 SET RESOURCE GROUP batch_low_priority 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很容易绑错会话,建议优先用用户级绑定而非运行时绑定
RESOURCE GROUP 仅对 SELECT 生效,DML 完全无视
这是硬限制,文档没明说但实测如此:哪怕你把 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 内核限流。它不控制“用了多少”,只控制“在哪跑、谁先跑”。即使绑了单核 + 最低优先级,一个复杂 SELECT 仍可能把那颗核吃满——你防不住它,只能让它别抢别人的核心。











