mysql resource groups 无法限制内存占用,仅支持cpu亲和性(vcpu绑定)和线程优先级(thread_priority)调度,且仅对select查询生效;内存控制需依赖os层cgroup、systemd memorymax或会话级变量约束。

MySQL 无法通过 Resource Groups 限制用户内存占用。 这是个常见误解——Resource Groups 在 MySQL 8.0+ 中只控制 CPU 时间片分配(THREAD_PRIORITY)和线程绑定,对内存完全无感知、无干预能力。
Resource Groups 能管什么、不能管什么
它只在查询执行阶段起作用,且仅限 SELECT 类只读语句(MySQL 8.0.19+ 才支持),INSERT/UPDATE/DELETE 和任何 DDL 都不受影响。内存消耗主要来自:sort_buffer_size、read_buffer_size、tmp_table_size 等会话级变量,而 Resource Groups 不读取、不覆盖、不限制这些值。
- 你给用户绑定了
rg_low,他照样能SET sort_buffer_size = 64M,只要没被禁掉SET权限 -
SHOW PROCESSLIST里看到的Resource Group列只是标识,不是内存隔离开关 - 即使把所有用户线程都塞进
THREAD_PRIORITY = -20的组,OOM killer 该杀进程还是杀
为什么有人以为 Resource Groups 能控内存
混淆点常出现在两个地方:
- 把“降低 CPU 优先级”等同于“降低资源消耗”——但低优先级线程仍可申请并持有大量内存,只是调度延迟而已
- 误读文档中 “resource group limits resource usage” 的表述,实际这里的 “resource” 指的是 CPU time,不是 memory/disk/connections
- 看到
VIRTUAL_CPU参数就联想 cgroups 的 CPUSet,但 MySQL 的VCPU只是逻辑编号,不映射到物理核或内存节点
真正能约束单用户内存行为的手段
必须绕开 MySQL 内部机制,从 OS 层或连接生命周期下手:
- 用
max_user_connections间接压内存:每个连接至少吃几十 KB 基础内存,限制并发连接数是最直接的会话内存封顶方式 - 在应用层统一
SET会话变量:连接池初始化时强制执行SET sort_buffer_size = 256K, read_buffer_size = 128K,比依赖用户自觉靠谱 - 用 systemd 的
MemoryMax=或 cgroup v2 的memory.max管整个mysqld进程,这是唯一硬性内存上限 - 禁止用户
SET权限(ALTER USER ... WITH MAX_USER_CONNECTIONS 1+REVOKE SUPER ON *.*),但得确认业务是否真不需要动态调缓冲区
Resource Groups 是个有用的 CPU 调度工具,但把它当内存防火墙,就像用漏勺挡洪水——方向错了,再使劲也拦不住。











