mysql 8.0资源组无法限制cpu使用率,仅支持vcpu绑定和thread_priority调度;必须指定type=user与真实vcpu范围才生效,且仅对select有效,dml完全绕过。

RESOURCE GROUP 不是 CPU 限流工具,它只影响“在哪跑”和“谁先跑”,不能把大查询的 CPU 使用率压到某个百分比。想靠它让慢 SELECT 占用更少算力,本质是靠绑定真实 VCPU + 调低 THREAD_PRIORITY,让内核在调度时把它往后排。
CREATE RESOURCE GROUP 必须带 TYPE 和 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 = 3、VCPU = 2-5、VCPU = 0,2,4
❌ 错误写法:VCPU = "0-3"(带引号)、VCPU = 8-15(越界)、VCPU = ""(空) - 务必预留至少 1–2 个核给
SYS_default,否则purge线程或元数据锁可能卡死mysqld
SET RESOURCE GROUP FOR thread_id 只影响下一条 SELECT
执行 SET RESOURCE GROUP slow_rg FOR 12345 后,线程 ID 12345 正在运行的那条大查询不会暂停、迁移或降优先级——它继续在原 CPU 上跑完。只有下一条语句才受新资源组约束。
- 想让限制“立即生效”,必须两步走:
先KILL QUERY 12345中断当前执行
再让应用重连,并确保连接后立刻执行SET RESOURCE GROUP或已通过ALTER USER ... RESOURCE GROUP预设 -
thread_id是performance_schema.threads.THREAD_ID,不是PROCESSLIST_ID;且需确认performance_schema已启用(默认关闭) - 目标线程状态不能是
Sleep,否则报错ERROR 3661 (HY000);也不能处于Waiting for table metadata lock等不可中断状态
资源组只对 SELECT 生效,DML 完全绕过
这是硬限制,不是配置问题。哪怕你把一个正在执行 UPDATE 的线程显式绑到低优先级资源组,它仍会在所有 CPU 上自由调度,CPU 占用不受控。
-
INSERT/UPDATE/DELETE/ALTER TABLE这类写操作完全不走资源组调度路径 - 验证是否生效,只测
SELECT SLEEP(10)或复杂只读查询,别拿UPDATE WHERE去试 - 如果负载以批量写入为主(如 ETL、日志归档),资源组对这部分 CPU 占用毫无约束力,此时应转向外部手段,如
cgroups或MAX_UPDATES_PER_HOUR
THREAD_PRIORITY 生效前提很苛刻
THREAD_PRIORITY 不是 MySQL 自己调度的权重,它只是把 nice 值透传给 Linux 内核。没权限、没能力,设了等于白设。
- 必须给
mysqld进程授予CAP_SYS_NICE能力:setcap cap_sys_nice+ep /usr/sbin/mysqld - 用户线程的合法范围是
0到19(数字越大,优先级越低);设-10会直接报错ER_RESOURCE_GROUP_NO_ACCESS - 优先级差值要足够明显:比如核心业务设
0,报表任务设15,差 15 级才能在高负载下观察到响应延迟差异











