mysql 8.0资源组仅限select绑定cpu核心并调低调度优先级,对insert/update/delete完全无效;必须指定type=user和真实vcpu范围才生效,且需cap_sys_nice权限支持thread_priority。

MySQL 8.0 的资源组不能限制 SQL 的 CPU 使用率或内存占用,只能把 SELECT 查询绑定到指定 CPU 核心,并调低其调度优先级;INSERT/UPDATE/DELETE 完全无效。
CREATE RESOURCE GROUP 必须带 TYPE 和 VCPU 才真正生效
漏掉 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 = 4-7有效,写VCPU = 8-15或带引号的"0-3"会静默失败或报错 - 支持三种格式:
0(单核)、2-5(连续)、0,2,4(离散),不能混用,也不能留空 - 务必预留至少 1–2 个核给
SYS_default,否则 MySQL 自身可能卡死在 metadata lock 或 purge 线程上
SET RESOURCE GROUP FOR thread_id 只影响后续查询
执行 SET RESOURCE GROUP slow_rg FOR 12345 后,线程 ID 12345 正在运行的那条慢 SQL 不会暂停、迁移或降优先级——它继续在原 CPU 上跑完。只有下一条语句才受新资源组约束。
- 查线程 ID 必须用
performance_schema.threads.THREAD_ID,不是PROCESSLIST_ID;且需确保performance_schema已启用(默认关闭) - 目标线程状态不能是
Sleep,否则报错ERROR 3661 (HY000);也不能处于Waiting for table metadata lock等不可中断状态 - 若想让限制立即生效,必须先
KILL QUERY 12345,再让应用重试,并确保重试连接已绑定资源组(比如通过ALTER USER ... RESOURCE GROUP) - 连接池复用连接时,
THREAD_ID频繁变化,临时SET很容易绑错会话,建议优先用用户级绑定而非运行时绑定
资源组只对 SELECT 生效,写操作完全绕过
这是硬限制:哪怕你把 UPDATE 所在线程显式绑到低优先级资源组,它仍会在所有 CPU 上自由调度,CPU 占用不受控。MySQL 8.0 的资源组仅作用于优化器选中的 SELECT 查询路径。
- 所有写操作类语句(
INSERT、UPDATE、DELETE、ALTER TABLE)完全绕过资源组调度逻辑 - 存储过程、触发器、事件中无法动态调用
SET RESOURCE GROUP,只能由客户端或 DBA 在会话层主动干预 - 如果真要压制写操作资源消耗,得靠外部手段:比如
cgroups控制 mysqld 进程整体 CPU/内存,或在代理层(如 ProxySQL)做限流
THREAD_PRIORITY 在 Linux 上需要 CAP_SYS_NICE 才实际生效
资源组的 THREAD_PRIORITY 参数(范围 -20 到 19)本质是映射 Linux 的 nice 值,但 MySQL 默认无权调整线程优先级。没开能力时设了也等于没设。
- 必须提前给
mysqld进程授予权限:setcap cap_sys_nice+ep /usr/sbin/mysqld -
USER类型资源组只能设0–19,负值仅SYSTEM组可用 - 资源组不是“限频”,而是“在哪跑、谁先跑”:即使绑到单核 + 最低优先级,该线程仍可能占满那个核——只是其他高优线程能抢走 CPU 时间
- 确认是否生效可看
ps -eo pid,tid,nice,comm | grep mysqld,对比线程的nice值是否变化
真正难搞的是写操作和内存——资源组管不了,MAX_*_PER_HOUR 只卡频次不卡耗时,而 connection_memory_limit 虽能防 OOM,但需提前设阈值且对已运行查询无效。这些边界条件不厘清,配置再多资源组也压不住烂 SQL。











