mysql 8.0资源组不能限制cpu占用率,仅支持vcpu绑定和thread_priority调度,且只对后续select生效;create resource group必须指定type=user和真实vcpu范围,否则无效;dml语句完全绕过。

MySQL 8.0 的资源组不能限制 CPU 占用率(%),只能通过 VCPU 绑定和 THREAD_PRIORITY 影响线程调度位置与优先级;它对 INSERT/UPDATE/DELETE 完全无效,仅对后续 SELECT 查询生效。
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:
✅ 支持格式:0(单核)、2-5(连续)、0,2,4(离散)
❌ 错误写法:"0-3"(带引号)、8-15(越界)、VCPU = ""(空值) - 务必预留至少 1–2 个核给
SYS_default,否则purge线程或metadata lock可能卡死 mysqld
SET RESOURCE GROUP FOR thread_id 只影响后续查询,不中断当前执行
执行 SET RESOURCE GROUP slow_rg FOR 12345 后,线程 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 'user'@'%' RESOURCE GROUP = slow_rg)
资源组只对 SELECT 生效,DML 完全绕过
这是硬限制,不是配置问题。哪怕你把一个正在执行 UPDATE 的线程显式绑到低优先级资源组,它仍会在所有 CPU 上自由调度,CPU 占用不受控。
- MySQL 8.0 的资源组仅作用于优化器选中的
SELECT查询路径 -
INSERT、UPDATE、DELETE、ALTER TABLE等写操作类语句完全绕过资源组调度逻辑 - 验证是否生效,只能测纯读语句,比如:
SELECT SLEEP(10);;别拿UPDATE ... WHERE ...去试
THREAD_PRIORITY 在 Linux 上需 CAP_SYS_NICE 权限才真正生效
没这个能力,设了 THREAD_PRIORITY 等于白设。常见部署中容易被忽略的关键点:
- 需用 root 执行:
setcap cap_sys_nice+ep /usr/sbin/mysqld - phpEnv 或 Windows 官方版默认不支持资源组:
phpEnv启动的 MySQL 通常未启用resource_group_enabled=ON;Windows 社区版二进制常编译禁用该功能,CREATE RESOURCE GROUP直接报错ERROR 1235 - 连接池复用连接时,
THREAD_ID频繁变化,临时SET RESOURCE GROUP很容易绑错会话;建议优先用用户级绑定:ALTER USER 'report_user'@'%' RESOURCE GROUP = batch_low_priority
最易被忽略的是:资源组不是“限 CPU 使用率”,而是“指定在哪跑、谁先跑”;它不干预执行强度,也不终止长查询——想压住烂 SQL 的整体 CPU 消耗,得靠外部 cgroups 或查询重写 + max_execution_time 配合。











