mysql 8.0资源组无法限制用户级cpu占用率,仅能对后续select查询做vcpu绑定和调度优先级干预;必须显式指定type=user和真实vcpu范围,且需cap_sys_nice权限,insert/update/delete完全无效。

MySQL 8.0 的资源组不能限制用户级 CPU 占用率,只能对特定线程的后续 SELECT 查询做 CPU 核心绑定和调度优先级干预,且必须显式绑定、满足权限与系统前提 —— 想靠它“压住一个用户整体 CPU 消耗”,本质上行不通。
CREATE RESOURCE GROUP 必须带 TYPE 和 VCPU 才真正生效
漏掉 TYPE = USER 或 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_rg 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 在会话层主动干预 - 如果真要压制写操作资源消耗,得靠外部手段:比如
cgroups控制mysqld进程整体 CPU/内存,或在代理层限流
THREAD_PRIORITY 在 Linux 上需 CAP_SYS_NICE 权限才生效
THREAD_PRIORITY 是 Linux nice 值映射,范围 -20(最高)到 19(最低),但用户线程只能设 0–19;没开 CAP_SYS_NICE 能力时,设了也等于没设。
- 必须提前给
mysqld进程授予权限:setcap cap_sys_nice+ep /usr/sbin/mysqld - 运行
getcap /usr/sbin/mysqld确认是否含cap_sys_nice - 优先级差异只有在多线程争抢同一组
VCPU时才明显;如果VCPU隔离彻底(比如只给慢查询分VCPU = 3),优先级几乎没作用 - 资源组本质是操作系统级调度干预,不是 MySQL 内核限流 —— 它不控制“用了多少 CPU”,只控制“在哪跑、谁先跑”
真正想限制一个用户的整体 CPU 消耗,别只盯着资源组:它连 UPDATE 都管不住,更别说内存或并发。生产环境该用 cgroups 控进程、用 MAX_QUERIES_PER_HOUR 卡频次、用代理层做请求级熔断 —— 资源组只是其中一环,而且是最容易误判效果的那一环。











