resource groups 是 mysql 8.0 引入的仅控制 cpu 时间片调度优先级的机制,仅在 innodb_thread_concurrency > 0 时生效;它不是资源配额系统,不提供内存、磁盘 i/o 或锁的隔离与限制。

Resource Groups 是什么,不是什么
MySQL 8.0 引入的 Resource Groups 不是资源配额系统,也不提供内存或磁盘 I/O 的硬限制。它只控制 CPU 时间片的调度优先级,且仅对使用 innodb_thread_concurrency > 0 的场景生效。换句话说:它只在你主动启用线程并发控制的前提下,才对工作线程(如用户查询线程、后台 purge 线程)的 CPU 调度产生影响;默认 innodb_thread_concurrency = 0 时,Resource Groups 完全不生效。
为什么必须搭配 innodb_thread_concurrency 才能起作用
MySQL 的线程调度模型里,Resource Groups 的优先级策略(SYSTEM / USER)只有在 InnoDB 主动参与线程节流时才被读取。而这个节流开关就是 innodb_thread_concurrency:
- 设为 0 → InnoDB 放开所有线程,不干预调度,
Resource Groups被忽略 - 设为正整数(如 16)→ InnoDB 启用内部线程队列,此时会检查线程所属的
Resource Group,并按其VCPU列表和priority值决定调度顺序
常见误操作:只建了 group、把线程绑进去了,但没改 innodb_thread_concurrency,结果发现 CPU 使用毫无变化——本质是调度器根本没启动。
绑定线程时容易踩的坑
用 SET RESOURCE GROUP 绑定线程,有三个关键约束常被忽略:
-
RESOURCE GROUP必须在会话创建前存在,且类型匹配:用户线程只能绑USER类型 group,系统线程(如purge)只能绑SYSTEM类型 - 绑定后无法在同个会话中切换 group,必须断开重连;临时线程(如复制 IO/SQL 线程)不能手动绑定
-
VCPU列表不是“分配 CPU 核心”,而是告诉调度器“允许在这个 CPU 集合内迁移”,若指定的 vCPU 在宿主机上不存在(比如容器里只暴露了 2 个核,却写了VCPU = (4,5)),绑定会静默失败
验证是否生效,不要只看 SELECT * FROM INFORMATION_SCHEMA.RESOURCE_GROUPS,得查 performance_schema.threads 表里的 RESOURCE_GROUP 字段,再结合 top -H -p $(pgrep mysqld) 观察线程实际 CPU 亲和性。
真正隔离的是什么,不是什么
Resource Groups 只隔离 CPU 时间片的抢占顺序,对以下资源完全无感:
- 内存:不会限制 buffer pool 占用、不会阻止大查询触发内存 swap
- 磁盘 I/O:不控制
innodb_io_capacity或read_ahead行为,高优先级 group 的查询仍可能因刷脏页阻塞 - 锁与事务:不会降低死锁概率,也不会让高优先级线程跳过行锁等待
所以它不适合解决“某个慢查询拖垮整个实例”的问题——那是要靠 max_execution_time、语句重写或物理资源扩容。它的定位很窄:在多租户或混合负载场景下,确保后台统计线程不抢走 OLTP 查询的 CPU 时间片。这点容易被文档里“resource isolation”这个词带偏。











