MySQL资源组用于管控用户会话的CPU调度与线程优先级,而非绑定数据库;需先创建资源组,再通过ALTER USER或SET RESOURCE GROUP将用户或会话分配其中,配合VCPU亲和性与THREAD_PRIORITY实现负载隔离。

CREATE RESOURCE GROUP 不能绑定数据库,只能绑定用户或会话
很多人误以为可以在 CREATE DATABASE 时指定资源组,这是错的。MySQL 的资源组(Resource Groups)不作用于数据库对象本身,而是作用于执行 SQL 的线程——也就是用户连接或具体会话。换句话说,你控制的是“谁在跑 SQL”,而不是“SQL 操作哪个库”。
- 资源组生效的前提是:用户已存在,且拥有
RESOURCE_GROUP_ADMIN或RESOURCE_GROUP_USER权限 -
TYPE = USER的资源组只能分配给普通用户连接;TYPE = SYSTEM只能用于 MySQL 内部线程(如purge_thread),不可手动绑定用户 - 默认所有新用户都落在
USR_default资源组里,不做显式分配就等于没隔离
VCPU 设置不是硬隔离,而是 CPU 亲和性调度倾向
VCPU = '0-3' 看起来像“只允许用这 4 个核”,但实际只是告诉调度器:“优先把该组线程扔到这些核上跑”。物理核仍可被多个资源组共用,真正起隔离作用的是 THREAD_PRIORITY 和 OS 层的 CFS 调度策略。
- 如果你的机器只有 4 核,却给两个资源组都设
VCPU = '0-3',它们依然会竞争 CPU 时间片,只是优先级不同 - 更有效的做法是错开 VCPU 范围(比如 OLTP 用
0-1,批处理用2-3),再配合THREAD_PRIORITY = -10和10形成两级压制 - 运行
cat /proc/cpuinfo | grep processor确认真实核心数,避免写错VCPU导致语句报错ER_RESOURCE_GROUP_VCPU_INVALID
ALTER USER ... RESOURCE GROUP 是即时生效的,但仅对新连接有效
执行 ALTER USER 'batch_user'@'%' RESOURCE GROUP = batch_low_priority 后,已存在的连接不会自动切换资源组。必须让该用户断开重连,或者用 SET RESOURCE GROUP 在会话内手动切。
- 对已有连接强制切换:登录后执行
SET RESOURCE GROUP batch_low_priority,该会话后续所有 SQL 都受控 - 若用连接池(如 HikariCP),需确保连接池配置了
connectionInitSql=SET RESOURCE GROUP ...,否则每次取连接都可能回到USR_default - 注意权限检查:执行
SET RESOURCE GROUP需要用户有RESOURCE_GROUP_USER权限,不是GRANT ALL就自动包含
资源组无法限制内存或磁盘 I/O,仅影响 CPU 调度
这是最容易被高估的一点。Resource Groups 在 MySQL 8.0 中只管控 CPU 时间片分配和线程调度优先级,它不控制缓冲池大小、临时表内存、sort_buffer、磁盘读写带宽或网络吞吐。
- 一个低优先级资源组里的 SQL 如果触发大量磁盘排序,照样能把 I/O 打满,拖慢其他业务
- 想压住内存消耗,得靠
max_heap_table_size、tmp_table_size、sort_buffer_size这类会话级变量,或用max_execution_time配合KILL QUERY做兜底 - 真正要实现全链路资源约束,得结合 Linux cgroups v2(比如
cpu.max+memory.max)做外层管控,MySQL 层只做精细调度
资源组不是银弹,它解决的是“CPU 时间抢不过来”的问题,而不是“SQL 写得太烂”或“配置太松”的问题。上线前务必在测试环境模拟高并发混合负载,用 SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST 和 top -H -p $(pgrep mysqld) 对照验证线程是否真进了目标 VCPU 和优先级。











