create resource group 语句必须显式指定 type 和 vcpu 才能生效,否则虽创建成功但无 cpu 隔离效果;type 为 user 或 system(用户线程仅可用 user),vcpu 必须为有效逻辑核范围(如 0、1-2),thread_priority 在 linux 需 root 权限与 cap_sys_nice 才真正生效。

CREATE RESOURCE GROUP 语句必须带 TYPE 和 VCPU 才能生效
MySQL 8.0.19+ 的 CREATE RESOURCE GROUP 不是“声明即生效”,漏掉关键参数会导致资源组创建成功但实际无约束力。常见错误是只写 CREATE RESOURCE GROUP rg_name;,结果查 INFORMATION_SCHEMA.RESOURCE_GROUPS 发现 VCPU 字段为 NULL 或 0-0,这种组绑定线程后完全不隔离 CPU。
正确写法必须显式指定类型和 CPU 绑定范围:
CREATE RESOURCE GROUP report_bg TYPE = USER VCPU = 2-3 THREAD_PRIORITY = 15;
-
TYPE = USER是强制项,SYSTEM类型仅限 MySQL 内部线程使用,用户无法绑定 -
VCPU必须是有效范围(如0、1-2、0,2,4),不能留空或填无效值(如-1) -
THREAD_PRIORITY在 Linux 上需 root 权限 +CAP_SYS_NICE能力才真正生效;没开能力时设了也等于没设
SET RESOURCE GROUP FOR thread_id 只对当前会话的后续查询起作用
资源组不是“永久绑定线程”,而是“动态调度策略”。执行 SET RESOURCE GROUP report_bg FOR 12345 后,线程 ID 12345 的**下一个查询开始**才会被调度到指定 VCPU 上——已运行中的查询不受影响,也不会中断。
这意味着你不能靠它“实时掐断”一个正在跑的慢 SQL,只能预防后续请求。典型误用场景:
- 查
performance_schema.threads找到PROCESSLIST_TIME > 60的线程,直接SET RESOURCE GROUP low_prio FOR xxx—— 没用,那条 SQL 已在跑了 - 应用连接池复用连接,线程 ID 复用频繁,
SET命令可能绑错会话 - 未启用
performance_schema(默认关闭),根本查不到活跃线程 ID
真要干预运行中查询,得先 KILL QUERY xxx,再让应用重试并确保重试连接绑定了资源组。
资源组只控制 SELECT,INSERT/UPDATE/DELETE 默认不生效
这是最容易被忽略的硬限制:RESOURCE GROUP 在 MySQL 8.0 中**仅对优化器选择的 SELECT 查询生效**。所有写操作(INSERT、UPDATE、DELETE、ALTER TABLE)完全绕过资源组调度,哪怕你显式绑定了线程,它们仍跑在默认 CPU 上。
验证方式很简单:
SELECT * FROM INFORMATION_SCHEMA.RESOURCE_GROUPS WHERE RESOURCE_GROUP_NAME = 'report_bg';
如果看到 TYPE 是 USER,但 ENABLE 是 DISABLED,说明该组当前未参与调度;更隐蔽的是它明明 ENABLED,但写操作监控里 CPU 使用率毫无变化。
- 如果你的任务含大量
INSERT ... SELECT,注意只有 SELECT 那部分受控,INSERT 部分仍自由占用资源 - 想限制写操作 CPU,目前唯一办法是降低其并发度(用
MAX_UPDATES_PER_HOUR)或改用外部 cgroups - 不要依赖
THREAD_PRIORITY降级来“拖慢”写操作——Linux 调度器对 I/O 密集型线程优先级调整效果极弱
VCPU 绑定依赖宿主机真实拓扑,虚拟机/容器常出问题
VCPU = 0-1 看似简单,但在容器或云主机上极易失效。MySQL 启动时读取 /proc/cpuinfo 确定可用 vCPU 数量,如果容器只分配了 2 个 vCPU,但宿主机有 32 核,VCPU = 2-3 就直接报错或静默失败。
检查步骤必须闭环:
- 进容器执行
cat /proc/cpuinfo | grep processor | wc -l,确认可见核数 - 查 MySQL:
SELECT * FROM INFORMATION_SCHEMA.RESOURCE_GROUPS;,看VCPU列是否与预期一致 - 查系统:
SELECT THREAD_ID, RESOURCE_GROUP FROM performance_schema.threads WHERE TYPE = 'FOREGROUND';,确认线程确实落在目标组
常见坑:
- Docker run 用
--cpuset-cpus="0-1"限制容器 CPU,但 MySQL 仍可能看到全部宿主机核数(取决于 cgroup v1/v2 和 kernel 版本) - Kubernetes Pod 的
resources.limits.cpu是软限制,MySQL 无法感知,VCPU设置仍按宿主机算 - 宝塔面板等一键安装包默认禁用
performance_schema,导致你连线程都查不到
真正可控的起点,永远是先确认宿主机层面的 CPU 可见性,再谈 MySQL 层面的绑定——否则所有配置都是空中楼阁。











