create resource group 必须同时指定 type 和 vcpu 才生效,否则无 cpu 隔离效果;type 限 user/system,vcpu 需为真实逻辑核 id;set resource group 仅影响下一条语句;资源组仅约束 select,dml 完全绕过;thread_priority 需配合 vcpu 绑定且依赖 os 调度。

CREATE RESOURCE GROUP 必须带 TYPE 和 VCPU 才真正生效
不填 TYPE 或 VCPU 的资源组,看起来创建成功,但实际没有任何 CPU 隔离效果。查 INFORMATION_SCHEMA.RESOURCE_GROUPS 会发现 VCPU_IDS 是 NULL 或 0-0,绑给线程后照样跑满所有核。
-
TYPE只能是USER(用户线程)或SYSTEM(MySQL 内部线程),普通用户只能用USER -
VCPU必须填服务器真实存在的逻辑 CPU ID,比如 8 线程机器 ID 是 0–7,写VCPU = 4-7有效,写VCPU = "0-3"(带引号)或VCPU = 8-15直接报错或失效 - 支持三种格式:
0(单核)、2-5(连续)、0,2,4(离散),不能混用,也不能留空 - 务必预留至少 1–2 个核给
SYS_internal等系统线程,否则 mysqld 可能卡死在 metadata lock 或 purge 上
SET RESOURCE GROUP FOR thread_id 只影响下一条语句
这是最常被误用的点:执行 SET RESOURCE GROUP slow_rg FOR 12345 后,线程 ID 12345 正在跑的那条慢 SELECT 不会暂停、不会迁移、也不会降优先级——它继续在原 CPU 上跑完。只有下一条语句才受新资源组约束。
- 查线程 ID 必须用
performance_schema.threads.THREAD_ID(不是PROCESSLIST_ID),且需确认performance_schema已启用 - 目标线程状态不能是
Sleep,否则报错ERROR 3661 (HY000);也不能处于Waiting for table metadata lock等不可中断状态 - 想立即生效,得先
KILL QUERY 12345,再让应用重连,并确保连接后立刻执行SET RESOURCE GROUP - 连接池场景下
THREAD_ID复用频繁,临时绑定极易错位,建议优先用ALTER USER ... RESOURCE GROUP做用户级绑定
资源组只对 SELECT 生效,DML 完全绕过
INSERT/UPDATE/DELETE/ALTER TABLE 这类写操作,哪怕线程已绑定到低优先级资源组,也完全不受控,照样在默认 CPU 上全速跑。这不是 bug,是 MySQL 8.0 的硬限制——资源组只参与优化器选中的 SELECT 查询路径调度。
- 如果你的负载以批量写入为主(如 ETL、日志归档),资源组对这部分 CPU 占用毫无约束力
- 别拿
UPDATE ... WHERE去验证资源组是否生效,只测SELECT SLEEP(10)或复杂只读查询 - 写操作类语句无法通过资源组实现“CPU 核心锁定”,此时应转向外部手段,如
cgroups或MAX_UPDATES_PER_HOUR - 存储过程、触发器、事件中无法动态调用
SET RESOURCE GROUP,只能由客户端或 DBA 在会话层主动干预
THREAD_PRIORITY 生效前提和实际效果很有限
THREAD_PRIORITY 不是 CPU 使用率上限,只是告诉操作系统“这个线程更想抢到时间片”。它只有在多个线程争抢同一组 VCPU 时才起作用;如果已用 VCPU = 3 把线程钉死在单核上,优先级几乎没意义。
- 用户资源组允许的优先级范围是
0–19,填-5会直接报错;只有具备SYSTEM权限的线程才能设-20 - Linux 下必须提前给
mysqld进程授予CAP_SYS_NICE能力:setcap cap_sys_nice+ep /usr/sbin/mysqld,否则设了等于白设 - 优先级差值要足够明显:比如 OLTP 设
-10,报表设10,差 20 级,才能在高负载下观察到响应延迟差异 - phpEnv 或 Windows 官方版默认不支持资源组,因为编译时未启用该功能,
CREATE RESOURCE GROUP会直接报错
VCPU 绑定 + THREAD_PRIORITY 组合策略,而不是单独某一项;且整个机制依赖操作系统调度,MySQL 自身不做时间片切分或限流。容易被忽略的是:它不控制“用了多少 CPU”,只控制“在哪跑、谁先跑”。











