mysql 8.0资源组仅限select语句生效,需同时指定type=user和真实vcpu列表才真正绑定cpu核心并生效,写操作完全无视;thread_priority需cap_sys_nice权限且仅在多线程争抢时体现效果。

MySQL 8.0 的资源组不能限制 CPU 使用率,只能绑定线程到指定逻辑 CPU 核心(VCPU)并调整调度优先级;漏掉 TYPE 或 VCPU 参数,资源组就等于没建。
CREATE RESOURCE GROUP 必须带 TYPE 和 VCPU 才真正生效
不写 TYPE = USER 和真实 VCPU 列表,语句能执行成功,但查 INFORMATION_SCHEMA.RESOURCE_GROUPS 会发现 VCPU_IDS 是 NULL 或 0-0,绑给线程后毫无隔离效果。
-
TYPE只能是USER(用户线程)或SYSTEM(仅 MySQL 内部线程可用),普通用户线程只能用USER -
VCPU必须填服务器真实存在的逻辑 CPU ID,比如 8 线程机器 ID 是0–7,写VCPU = 4-7有效,写VCPU = 8-15或VCPU = "0-3"(带引号)直接报错或静默失效 - 支持三种格式:
0(单核)、2-5(连续)、0,2,4(离散),不能混用,也不能留空 - 务必预留至少 1–2 个核给系统线程(如
SYS_default),否则mysqld自身可能卡死在 metadata lock 或 purge 上
SET RESOURCE GROUP FOR thread_id 只影响下一条 SELECT
执行 SET RESOURCE GROUP slow_sql FOR 12345 后,线程 ID 12345 正在运行的慢查询不会中断、不会迁移、也不会降速——它继续在原 CPU 上跑完。只有下一条语句才受新资源组约束,且仅对 SELECT 生效。
- 查线程 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 生效,INSERT/UPDATE/DELETE 完全无视
这是硬限制,文档没明说但实测如此:哪怕你把 UPDATE 语句所在的线程绑到最低优先级资源组,它仍会在所有 CPU 上自由调度,CPU 占用不受控。资源组只作用于优化器选中的 SELECT 查询路径。
- 所有写操作类语句(
INSERT、UPDATE、DELETE、ALTER TABLE)完全绕过资源组调度逻辑 - 存储过程、触发器、事件中无法动态调用
SET RESOURCE GROUP,只能由客户端或 DBA 在会话层主动干预 - 如果负载以写为主(比如 ETL 导入、日志归档),资源组对这部分 CPU 占用毫无约束力
- 验证是否生效,只测
SELECT SLEEP(10)这类纯读语句,别拿UPDATE WHERE去试
THREAD_PRIORITY 生效需要 CAP_SYS_NICE 能力
THREAD_PRIORITY 在 Linux 上不是设了就起作用。MySQL 进程必须提前被授予 CAP_SYS_NICE 能力,否则设置的优先级会被内核忽略。
- 执行
setcap cap_sys_nice+ep /usr/sbin/mysqld(路径按实际调整),再重启mysqld - 用户资源组允许的
THREAD_PRIORITY范围是0–19,填-5会直接报错;只有SYSTEM类型线程才能设负值 - 优先级差异只有在多线程争抢同一组
VCPU时才明显;如果VCPU隔离彻底(比如只给slow_sql分配单核),优先级影响很小 - Windows/macOS 不支持资源组;phpEnv 或官方 Windows 社区版二进制默认编译禁用该功能,
CREATE RESOURCE GROUP会直接报错
真正要压住烂 SQL 的 CPU,得靠组合:VCPU 绑定 + 明确的 THREAD_PRIORITY + 应用层主动绑定 + 预留系统核;而写操作类负载,资源组根本不管用,得换 MAX_UPDATES_PER_HOUR 或 OS 层 cgroups。











