mysql 8.0 的 resource group 仅能限制 cpu 时间片调度(vcpu 绑定与调度优先级),不能限制内存、磁盘 i/o、网络带宽、锁等待或事务执行。

MySQL 8.0 的 RESOURCE GROUP 能限制哪些资源?
只能限制 CPU 时间片调度(CPU_ID 绑定 + VCPU 配额),不能限制内存、磁盘 I/O 或网络带宽。MySQL 的 Resource Groups 是基于 Linux cgroups v1 的轻量级 CPU 调度控制,底层依赖 mysqld 进程运行在支持 cpuset 和 cpu 子系统的系统上(如主流 CentOS/RHEL 7+/Ubuntu 18.04+)。它不干预查询计划、不终止长事务、也不影响锁等待行为。
常见误判是以为能“限内存”或“杀慢查询”——这两者得靠 max_execution_time、innodb_buffer_pool_size 或第三方代理(如 ProxySQL)实现。
如何为某条 SELECT 查询绑定到指定 Resource Group?
必须通过 SET RESOURCE GROUP 显式声明会话级绑定,且仅对后续**新发起的语句**生效;已执行中的语句不受影响。关键点在于:该语法只接受 SELECT、INSERT、UPDATE、DELETE、REPLACE 和 DO,不支持 DDL(如 CREATE TABLE)或管理命令(如 SHOW)。
- 先创建组:
CREATE RESOURCE GROUP rg_low_cpu TYPE=USER VCPU=0-1; - 再在会话中启用:
SET RESOURCE GROUP rg_low_cpu; - 然后执行目标语句:
SELECT COUNT(*) FROM huge_table WHERE ...; - 恢复默认组:
SET RESOURCE GROUP default;(否则整个会话都受限)
注意:VCPU=0-1 表示允许调度到逻辑 CPU 0 和 1,不是“最多用 2 个核”,而是“只能在这两个核上跑”。若物理机只有 2 核,这反而可能造成争抢——实际应结合 top -H -p $(pgrep mysqld) 观察线程分布后再配。
为什么 SET RESOURCE GROUP 执行后没效果?
最常见三个原因:
- 用户没有
RESOURCE_GROUP_ADMIN权限 —— 必须显式授权:GRANT RESOURCE_GROUP_ADMIN ON *.* TO 'app_user'@'%'; - MySQL 启动时未启用 Resource Groups —— 检查
SELECT * FROM performance_schema.setup_actors;中RESOURCE_GROUP列是否为ENABLED;若否,需在配置文件加resource_group_enabled=ON并重启 - 语句被优化器改写或走预编译缓存 —— 尤其在使用连接池(如 HikariCP)时,
SET RESOURCE GROUP可能被复用连接覆盖。建议在应用层每次执行前重置:SET RESOURCE GROUP ...; SELECT ...;放在同一事务或同一请求内
还有一种静默失败:当指定的 VCPU 范围超出系统实际 CPU 数(如设 VCPU=4-7 但机器只有 4 核),MySQL 不报错,但组实际不可用 —— 查 performance_schema.resource_groups 表,看 ACTIVE_THREADS 是否始终为 0。
和 max_execution_time 或 sys.schema_table_statistics_with_buffer 比,Resource Groups 适合什么场景?
它唯一不可替代的价值是:**隔离 CPU 调度优先级,避免 OLAP 查询拖垮 OLTP 响应延迟**。比如定时报表任务(SELECT ... FROM sales JOIN orders GROUP BY ...)和核心下单接口共用同一实例时,可将报表会话绑到低优先级 VCPU 组,而保持下单线程始终可用高优先级核。
但它不解决以下问题:
- 查询本身很慢 → 应优化索引或执行计划
- 结果集太大导致网络/内存压力 → 需分页或压缩传输
- 并发太多压垮连接数 → 得调
max_connections或加读写分离
真正落地时,Resource Groups 往往只是整套资源治理中的一环;单独启用几乎看不到效果,必须配合 performance_schema 监控(如 events_statements_history_long 中的 RESOURCE_GROUP 字段)、应用层路由策略,以及 OS 层 cgroups 的协同配置。











