CREATE RESOURCE GROUP 的 VCPU 参数必须指定服务器真实存在的逻辑 CPU ID 集合(如 0、2-5、0,2,4),用于 CPU 亲和性控制,不可加引号、不可越界、不可覆盖系统线程所需核心,且仅对 SELECT 查询生效。

CREATE RESOURCE GROUP 时 VCPU 参数怎么填才有效
VCPU 不是“分配几个核”,而是指定线程可调度的逻辑 CPU 编号集合,本质是 CPU 亲和性(CPU affinity)控制。填错会导致资源组看似生效、实则无隔离效果。
常见错误现象:SELECT * FROM INFORMATION_SCHEMA.RESOURCE_GROUPS 显示 VCPU_IDS 是空或 0-15,但实际没压住 CPU;或者绑定了线程却仍在所有核上跑满。
- 先确认物理/逻辑 CPU 数量:
lscpu | grep "CPU(s):"或cat /proc/cpuinfo | grep processor | wc -l - VCPU 值必须是服务器真实存在的逻辑 CPU ID 范围,例如 4 核 8 线程机器,ID 是
0-7,填VCPU = 4-7才有意义 - 支持三种写法:
0(单核)、2-5(连续范围)、0,2,4(离散列表),不能写成VCPU = "0-3"(字符串引号会报错) - 留出至少 1–2 个核给系统线程(如
SYS_internal),否则 MySQL 自身可能卡顿
SET RESOURCE GROUP FOR thread_id 必须在查询前执行
资源组不会自动继承用户或数据库,必须显式绑定到运行中的线程 ID,且只对后续语句生效——已开始执行的查询不受影响。
容易踩的坑:以为创建完资源组、建了用户、甚至改了 ALTER USER ... RESOURCE GROUP 就万事大吉,结果慢 SQL 还是占满 CPU。
- 查活跃慢线程:
SELECT THREAD_ID, PROCESSLIST_INFO FROM performance_schema.threads WHERE TYPE = 'FOREGROUND' AND PROCESSLIST_TIME > 30 - 绑定前确认线程状态不是
sleep,否则SET RESOURCE GROUP ... FOR会报错ERROR 3661 (HY000) - 绑定后验证:
SELECT THREAD_ID, RESOURCE_GROUP FROM performance_schema.threads WHERE THREAD_ID = 123 - 不支持在存储过程、触发器或事件中动态绑定,只能由客户端或 DBA 主动干预
THREAD_PRIORITY 对 CPU 占用率的影响很有限
优先级 ≠ CPU 使用率上限。它只是告诉操作系统“这个线程更想抢到 CPU 时间片”,但在高负载下仍可能被调度满,尤其当其他线程优先级也低时。
很多人误以为设 THREAD_PRIORITY = 19 就等于“限速”,实际它无法阻止一个复杂 SELECT 吃光分配到的那几个核。
- 用户资源组允许的优先级范围是
0–19,填-5会直接报错 - 优先级差异只有在多线程争抢同一组 VCPU 时才明显;如果 VCPU 隔离彻底(比如只给 slow_sql 分
VCPU = 3),优先级几乎没作用 - 真正压 CPU 的是查询本身复杂度 + 并发数,THREAD_PRIORITY 只是辅助手段,别指望靠它替代索引优化或分页改写
资源组对 INSERT/UPDATE/DELETE 完全无效
MySQL 8.0.19+ 的 Resource Groups 仅对 SELECT 类只读查询生效,所有写操作(包括 INSERT ... SELECT 中的 SELECT 部分)都不会受控。
这意味着:你以为把报表用户塞进低优先级资源组就安全了,但如果它执行一条 UPDATE t1 SET x=(SELECT COUNT(*) FROM t2),那个子查询照样能跑满你分配的 VCPU。
- 检查是否生效最直接的方式:
SHOW PROCESSLIST看Command列,只有Query且State是executing的 SELECT 才可能被限制 - 写操作线程永远走
USR_default组,除非你手动SET RESOURCE GROUP ... FOR并且该线程当前正在执行 SELECT - 真要控写负载,得靠
MAX_UPDATES_PER_HOUR+ 连接池限并发 + 应用层拆分,Resource Groups 在这里只是摆设
Resource Groups 不是 cgroups,也不提供硬性配额;它是一层轻量级调度提示,依赖内核支持(需 setcap cap_sys_nice+ep /usr/sbin/mysqld),且只在 Linux 有效。一旦 VCPU 设置过宽、或没做线程绑定、或混用了写操作,就等于没设。


















