MySQL 8.0资源组不能限制CPU使用率,仅支持VCPU绑定与调度优先级;只对后续SELECT生效,对INSERT/UPDATE/DELETE完全无效;CREATE必须指定TYPE=USER和真实VCPU范围,否则无效。

MySQL 8.0 的资源组不能限制“CPU 使用率”,只能绑定线程到特定 CPU 核心(VCPU)并调整调度优先级;它对 INSERT/UPDATE/DELETE 完全无效,只影响后续的 SELECT 查询。
CREATE RESOURCE GROUP 必须带 TYPE 和 VCPU 才真正生效
漏掉任一关键参数,资源组就只是个空壳:查 INFORMATION_SCHEMA.RESOURCE_GROUPS 会发现 VCPU 字段是 NULL 或 0-0,绑定后线程照常跑满所有核。
-
TYPE = USER是强制项——用户线程只能用USER类型,SYSTEM仅供 MySQL 内部线程(如io_thread)使用 -
VCPU必须填服务器真实存在的逻辑 CPU ID,例如 8 核机器 ID 是0–7;支持格式:3(单核)、2-5(连续)、0,2,4(离散),不能加引号或写-1 - 务必预留至少 1–2 个核给系统线程(如
SYS_default),否则 mysqld 可能卡死在 metadata lock 或 purge 上
SET RESOURCE GROUP 只影响下一条 SELECT,不中断当前执行
这是最常被误用的点:执行 SET RESOURCE GROUP slow_sql FOR 12345 后,线程 ID 12345 正在跑的那条慢 SQL 不会暂停、迁移或降速——它继续在原 CPU 上跑完。只有下一条语句才受新资源组约束。
- 想让限制“立即生效”,必须先
KILL QUERY 12345,再让应用重连,并确保连接后立刻执行SET RESOURCE GROUP - 查线程 ID 要用
performance_schema.threads.THREAD_ID,不是PROCESSLIST_ID;且需确认performance_schema已启用(默认关闭) - 目标线程状态不能是
Sleep,也不能处于Waiting for table metadata lock等不可中断状态,否则报错ERROR 3661 (HY000)
资源组只对 SELECT 生效,写操作完全绕过
这是硬限制,不是配置错误:哪怕你把 UPDATE 所在线程绑到低优先级资源组,它仍会在所有 CPU 上自由调度,CPU 占用不受控。MySQL 8.0 的资源组仅作用于优化器选中的 SELECT 查询路径。
- 存储过程、触发器、事件中无法动态调用
SET RESOURCE GROUP,只能由客户端或 DBA 在会话层主动干预 - 连接池复用连接时,
THREAD_ID频繁变化,临时SET很容易绑错会话;建议优先用用户级绑定:ALTER USER 'report_user'@'%' RESOURCE GROUP = batch_low_priority -
THREAD_PRIORITY在 Linux 上需mysqld进程有CAP_SYS_NICE能力(setcap cap_sys_nice+ep /usr/sbin/mysqld),否则设了等于白设
phpEnv 或 Windows 官方版默认不支持资源组
phpEnv 启动的 MySQL 8.0 默认禁用资源组功能,因其底层未启用 resource_group=ON 启动参数;Windows 官方社区版二进制也常编译禁用该功能,CREATE RESOURCE GROUP 会直接报错 ERROR 1235。
- 验证是否支持:执行
SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'RESOURCE_GROUP',若无结果或状态非ACTIVE,说明不可用 - 替代方案更实际:用
MAX_QUERIES_PER_HOUR、MAX_UPDATES_PER_HOUR做频次硬限,它们不依赖启动参数,兼容所有 8.0+ 版本 - 真正需要隔离资源时,别只盯 MySQL 内置功能——外部 cgroups 或代理层(如 ProxySQL)才是写操作类负载的可行解
复杂点在于:资源组不是“开关式限流”,而是操作系统调度层面的协作机制;它要求你同时理解 MySQL 线程模型、Linux 调度策略、以及应用连接生命周期。一个参数填错、一个能力没开、一次绑定时机不对,整套逻辑就失效。


















