MySQL 8.0资源组不支持CPU使用率百分比限制,仅通过VCPU绑定和THREAD_PRIORITY实现CPU亲和性与调度优先级控制;其本质是操作系统级调度干预,非MySQL内核限流。

MySQL 8.0 资源组不能设 CPU 使用率百分比
资源组(Resource Groups)不提供类似 cgroups 的 cpu.cfs_quota_us 那样的硬性 CPU 时间配额。它只做两件事:VCPU 绑定(CPU 亲和性)和线程调度优先级控制。所谓“分配权重”,其实是通过 THREAD_PRIORITY 和操作系统调度器间接影响线程获得 CPU 时间的概率,不是 MySQL 自己做时间片切分或限流。
常见误解是以为设置 VCPU = 0-3 就能限制线程只用 4/8 核的算力——实际它只是告诉内核“这个线程尽量在 0~3 号逻辑 CPU 上跑”,如果这 4 个核全忙,而其他核空闲,该线程仍可能被调度到其他核(取决于内核策略),且不会因“超配”被 throttled。
如何用 VCPU + THREAD_PRIORITY 实现事实上的 CPU 倾斜
真正起作用的是组合策略:绑定专属 CPU 核心 + 设置高低优先级,让不同负载在线程调度层面错开竞争。
-
VCPU列表越小、越独立(如 OLTP 用0-1,报表用2-3),物理隔离性越强;混用核心(如都设0-3)基本等于没绑 -
THREAD_PRIORITY对用户线程有效范围是-20到19,但注意:普通用户线程无法设低于-10的值(MySQL 会拒绝,报错ER_RESOURCE_GROUP_NO_ACCESS),只有具备SYSTEM类型权限的线程才能设-20 - 优先级差值要足够明显:比如 OLTP 设
-10,报表设10,差 20 级,才能在高负载下观察到响应延迟差异 - 必须配合用户绑定才生效:光建资源组没用,得用
ALTER USER ... RESOURCE GROUP或运行时SET RESOURCE GROUP ... FOR thread_id
运行时给活跃线程指定资源组的实操要点
临时调整某个慢查询线程的资源归属,比改用户更灵活,但也更易出错。
- 先查目标线程 ID:
SELECT THREAD_ID, PROCESSLIST_USER, PROCESSLIST_INFO FROM performance_schema.threads WHERE PROCESSLIST_INFO LIKE '%SOME_SLOW_SQL%' - 确认该线程当前没被锁住或处于
Waiting for table metadata lock等不可中断状态,否则SET RESOURCE GROUP ... FOR ...会失败 - 执行切换:
SET RESOURCE GROUP batch_low_priority FOR 12345(12345是THREAD_ID,不是PROCESSLIST_ID) - 切换后不会中断当前 SQL,只影响后续新语句的调度行为;若想立即生效,需 kill 后重连或等当前语句结束
- 注意权限:执行者需有
RESOURCE_GROUP_USER权限,且目标线程不能属于SYSTEM类型(如io_thread)
为什么 INFORMATION_SCHEMA.RESOURCE_GROUPS 查不到你的组
新建资源组后查 INFORMATION_SCHEMA.RESOURCE_GROUPS 返回空?大概率是忘了启用。
- 创建时默认是
ENABLE,但某些部署脚本或自动化工具可能显式加了DISABLE - 检查语句是否带
DISABLE:CREATE RESOURCE GROUP rg_name TYPE=USER VCPU=0 THREAD_PRIORITY=0 DISABLE; - 启用已存在的资源组:
ALTER RESOURCE GROUP rg_name ENABLE; - 还查不到?确认 MySQL 版本确实是 8.0.2+(资源组功能从 8.0.2 引入),且启动参数未禁用:
--disable-resource-group会导致整个功能不可用
最常被忽略的一点:资源组对 I/O 没有约束力,VCPU 和 THREAD_PRIORITY 都只影响 CPU 调度。如果你看到磁盘 IO 成瓶颈,资源组再怎么调也压不住。需要搭配 innodb_io_capacity、cgroups 或存储层限速来协同管控。











