MySQL 支持创建和管理资源组,并允许将服务器内运行的线程分配到特定的组,以便线程根据组可用的资源执行。组属性允许控制其资源,以启用或限制组中线程的资源消耗。DBA 可以根据不同工作负载的需要修改这些属性。
目前,CPU 时间是一种可管理的资源,用“虚拟 CPU”的概念来表示,它包括 CPU 内核、超线程、硬件线程等等。服务器在启动时确定有多少个虚拟 CPU 可用,具有适当权限的数据库管理员可以将这些 CPU 与资源组关联起来,并将线程分配到组中。
例如,为了管理不需要以高优先级执行的批处理作业的执行,DBA 可以创建一个名为 Batch
的资源组,并根据服务器的繁忙程度向上或向下调整其优先级。(也许分配给该组的批处理作业应该在白天以较低优先级运行,在晚上以较高优先级运行。)DBA 还可以调整可供该组使用的 CPU 集。可以启用或禁用组来控制是否可以将线程分配给它们。
以下各节描述了在 MySQL 中使用资源组的各个方面。
在某些平台或 MySQL 服务器配置中,资源组不可用或存在限制。尤其是,对于某些安装方法,Linux 系统可能需要一个手动步骤。有关详细信息,请参见 资源组限制。
这些功能为 MySQL 中的资源组管理提供了 SQL 接口。
SQL 语句允许创建、更改和删除资源组,并允许将线程分配到资源组。优化器提示允许将单个语句分配到资源组。
资源组权限提供对哪些用户可以执行资源组操作的控制。
信息模式
RESOURCE_GROUPS
表显示了有关资源组定义的信息,性能模式threads
表显示了每个线程的资源组分配。状态变量提供了每个管理 SQL 语句的执行计数。
资源组具有定义该组的属性。所有属性都可以在组创建时设置。有些属性在创建时固定;其他属性可以在以后的任何时间修改。
这些属性在资源组创建时定义,无法修改。
每个组都有一个名称。资源组名称与表和列名称类似,是标识符,在 SQL 语句中不需要加引号,除非它们包含特殊字符或保留字。组名称不区分大小写,长度最多为 64 个字符。
每个组都有一个类型,可以是
SYSTEM
或USER
。资源组类型会影响可分配给该组的优先级值的范围,如后面所述。此属性与允许的优先级之间的差异相结合,可以识别系统线程,以保护它们免受与用户线程争夺 CPU 资源的冲突。系统线程和用户线程分别对应于性能模式
threads
表中列出的后台线程和前台线程。
这些属性在资源组创建时定义,可以在以后的任何时间修改。
CPU 亲和力是资源组可以使用的一组虚拟 CPU。亲和力可以是可用 CPU 的任何非空子集。如果某个组没有亲和力,它可以使用所有可用 CPU。
线程优先级是分配到资源组的线程的执行优先级。优先级值介于 -20(最高优先级)和 19(最低优先级)之间。默认优先级为 0,系统组和用户组均如此。
系统组允许比用户组更高的优先级,确保用户线程永远不会比系统线程具有更高的优先级。
对于系统资源组,允许的优先级范围为 -20 到 0。
对于用户资源组,允许的优先级范围为 0 到 19。
每个组都可以启用或禁用,让管理员控制线程分配。线程只能分配到启用的组。
默认情况下,存在一个系统组和一个用户组,分别命名为SYS_default
和USR_default
。这些默认组无法删除,其属性也不能修改。每个默认组都没有 CPU 亲和性,优先级为 0。
新创建的系统线程和用户线程分别被分配到SYS_default
和USR_default
组。
对于用户定义的资源组,所有属性都在组创建时分配。组创建后,除了名称和类型属性外,其属性都可以修改。
要创建和管理用户定义的资源组,请使用以下 SQL 语句
这些语句需要RESOURCE_GROUP_ADMIN
权限。
要管理资源组分配,请使用以下功能
SET RESOURCE GROUP
将线程分配到一个组。请参见第 15.7.2.4 节,“SET RESOURCE GROUP 语句”。RESOURCE_GROUP
优化器提示将单个语句分配到一个组。请参见第 10.9.3 节,“优化器提示”。
这些操作需要RESOURCE_GROUP_ADMIN
或RESOURCE_GROUP_USER
权限。
资源组定义存储在resource_groups
数据字典表中,以便组在服务器重启时保留。因为resource_groups
是数据字典的一部分,用户无法直接访问它。可以使用信息架构RESOURCE_GROUPS
表来获取资源组信息,该表作为数据字典表的视图实现。请参见第 28.3.26 节,“INFORMATION_SCHEMA RESOURCE_GROUPS 表”。
最初,RESOURCE_GROUPS
表包含以下行,描述默认组
mysql> SELECT * FROM INFORMATION_SCHEMA.RESOURCE_GROUPS\G
*************************** 1. row ***************************
RESOURCE_GROUP_NAME: USR_default
RESOURCE_GROUP_TYPE: USER
RESOURCE_GROUP_ENABLED: 1
VCPU_IDS: 0-3
THREAD_PRIORITY: 0
*************************** 2. row ***************************
RESOURCE_GROUP_NAME: SYS_default
RESOURCE_GROUP_TYPE: SYSTEM
RESOURCE_GROUP_ENABLED: 1
VCPU_IDS: 0-3
THREAD_PRIORITY: 0
THREAD_PRIORITY
值为 0,表示默认优先级。 VCPU_IDS
值显示包含所有可用 CPU 的范围。对于默认组,显示的值会根据运行 MySQL 服务器的系统而有所不同。
之前的讨论中提到了一种场景,其中涉及一个名为Batch
的资源组,用于管理不需要以高优先级执行的批处理作业的执行。要创建这样的组,请使用类似于以下语句的语句
CREATE RESOURCE GROUP Batch
TYPE = USER
VCPU = 2-3 -- assumes a system with at least 4 CPUs
THREAD_PRIORITY = 10;
要验证资源组是否按预期创建,请检查RESOURCE_GROUPS
表
mysql> SELECT * FROM INFORMATION_SCHEMA.RESOURCE_GROUPS
WHERE RESOURCE_GROUP_NAME = 'Batch'\G
*************************** 1. row ***************************
RESOURCE_GROUP_NAME: Batch
RESOURCE_GROUP_TYPE: USER
RESOURCE_GROUP_ENABLED: 1
VCPU_IDS: 2-3
THREAD_PRIORITY: 10
如果THREAD_PRIORITY
值为 0 而不是 10,请检查您的平台或系统配置是否限制了资源组功能;请参见资源组限制。
要将线程分配到Batch
组,请执行以下操作
SET RESOURCE GROUP Batch FOR thread_id;
此后,命名线程中的语句将使用Batch
组资源执行。
如果会话本身的当前线程应该在Batch
组中,请在会话中执行以下语句
SET RESOURCE GROUP Batch;
此后,会话中的语句将使用Batch
组资源执行。
要使用Batch
组执行单个语句,请使用RESOURCE_GROUP
优化器提示
INSERT /*+ RESOURCE_GROUP(Batch) */ INTO t2 VALUES(2);
分配到Batch
组的线程将使用其资源执行,这些资源可以根据需要修改
当系统负载很高时,减少分配给该组的 CPU 数量,降低其优先级,或者(如所示)同时降低两者
ALTER RESOURCE GROUP Batch VCPU = 3 THREAD_PRIORITY = 19;
当系统负载较低时,增加分配给该组的 CPU 数量,提高其优先级,或者(如所示)同时提高两者
ALTER RESOURCE GROUP Batch VCPU = 0-3 THREAD_PRIORITY = 0;
在某些平台或 MySQL 服务器配置中,资源组不可用或存在限制
如果安装了线程池插件,则资源组不可用。
macOS 上的资源组不可用,因为 macOS 不提供将 CPU 绑定到线程的 API。
在 FreeBSD 和 Solaris 上,资源组线程优先级将被忽略。(实际上,所有线程都以优先级 0 运行。)尝试更改优先级会导致警告
mysql> ALTER RESOURCE GROUP abc THREAD_PRIORITY = 10; Query OK, 0 rows affected, 1 warning (0.18 sec) mysql> SHOW WARNINGS; +---------+------+-------------------------------------------------------------+ | Level | Code | Message | +---------+------+-------------------------------------------------------------+ | Warning | 4560 | Attribute thread_priority is ignored (using default value). | +---------+------+-------------------------------------------------------------+
在 Linux 上,除非设置了
CAP_SYS_NICE
功能,否则资源组线程优先级将被忽略。将CAP_SYS_NICE
功能授予进程可以启用一系列权限;请咨询http://man7.org/linux/man-pages/man7/capabilities.7.html,了解完整列表。启用此功能时请谨慎。在使用 systemd 和内核支持的环境功能(Linux 4.3 或更高版本)的 Linux 平台上,启用
CAP_SYS_NICE
功能的推荐方法是修改 MySQL 服务文件并保持mysqld 二进制文件不变。要调整 MySQL 的服务文件,请使用以下步骤运行适用于您的平台的相应命令
Oracle Linux、Red Hat 和 Fedora 系统
$> sudo systemctl edit mysqld
SUSE、Ubuntu 和 Debian 系统
$> sudo systemctl edit mysql
使用编辑器将以下文本添加到服务文件中
[Service] AmbientCapabilities=CAP_SYS_NICE
重启 MySQL 服务。
如果您无法像上面那样启用
CAP_SYS_NICE
功能,则可以使用setcap命令手动设置它,指定mysqld 可执行文件的路径名(这需要sudo访问权限)。您可以使用getcap检查功能。例如$> sudo setcap cap_sys_nice+ep /path/to/mysqld $> getcap /path/to/mysqld /path/to/mysqld = cap_sys_nice+ep
作为安全措施,将mysqld 二进制文件的执行权限限制为
root
用户和具有mysql
组成员资格的用户$> sudo chown root:mysql /path/to/mysqld $> sudo chmod 0750 /path/to/mysqld
重要如果需要手动使用setcap,则必须在每次重新安装后执行此操作。
在 Windows 上,线程以五个线程优先级级别之一运行。资源组线程优先级范围 -20 到 19 会映射到以下表中所示的那些级别。
表 7.6 Windows 上的资源组线程优先级
优先级范围 Windows 优先级级别 -20 到 -10 THREAD_PRIORITY_HIGHEST
-9 到 -1 THREAD_PRIORITY_ABOVE_NORMAL
0 THREAD_PRIORITY_NORMAL
1 到 10 THREAD_PRIORITY_BELOW_NORMAL
11 到 19 THREAD_PRIORITY_LOWEST