MySQL支持创建和管理资源组,并允许将服务器中运行的线程分配给特定的组,以便线程根据该组可用的资源执行。使用组属性可以控制其资源,以启用或限制组中线程的资源消耗。DBA可以根据不同的工作负载修改这些属性。
当前,CPU时间是一种可管理的资源,以“ 虚拟CPU ”的概念表示,该术语包括CPU内核,超线程,硬件线程等。服务器在启动时确定有多少个虚拟CPU可用,具有适当特权的数据库管理员可以将这些CPU与资源组相关联,并将线程分配给组。
例如,要管理不需要以高优先级执行的批处理作业的执行,DBA可以创建一个 Batch资源组,并根据服务器的繁忙程度上下调整其优先级。(也许分配给该组的批处理作业应在白天以较低的优先级运行,而在夜间以较高的优先级运行。)DBA还可以调整可用于该组的CPU组。可以启用或禁用组以控制是否可将线程分配给它们。
以下各节描述了MySQL中资源组使用的各个方面:
资源组组件
资源组属性
资源组管理
资源组复制
资源组限制
重要
在某些平台或MySQL服务器配置上,资源组不可用或有限制。特别是,对于某些安装方法,Linux系统可能需要手动操作。有关详细信息,请参见 资源组限制。
资源组组件
这些功能为MySQL中的资源组管理提供了SQL接口:
SQL语句允许创建,更改和删除资源组,并允许将线程分配给资源组。优化程序提示使您可以将单个语句分配给资源组。
资源组特权提供对哪些用户可以执行资源组操作的控制。
该 INFORMATION_SCHEMA.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语句:
CREATE RESOURCE GROUP创建一个新组。
CREATE RESOURCE GROUP语句
CREATE RESOURCE GROUP group_name
TYPE = {SYSTEM|USER}
[VCPU [=] vcpu_spec [, vcpu_spec] ...]
[THREAD_PRIORITY [=] N]
[ENABLE|DISABLE]
vcpu_spec: {N | M - N}
CREATE RESOURCE GROUP用于资源组管理(请参见 第5.1.15节“资源组”)。该语句创建一个新的资源组并分配其初始属性值。它需要RESOURCE_GROUP_ADMIN 特权。
group_name标识要创建的资源组。如果该组已经存在,则会发生错误。
该TYPE属性是必需的。它应该 SYSTEM用于系统资源组, USER对于用户资源组。群组类型会影响允许THREAD_PRIORITY 值,如下所述。
该VCPU属性表示CPU亲和力;也就是说,该组可以使用的一组虚拟CPU:
如果VCPU未给出,则资源组没有CPU关联,并且可以使用所有可用的CPU。
如果VCPU给出,则属性值是逗号分隔的CPU编号或范围的列表:
每个数字必须是介于0到CPU数− 1范围内的整数。例如,在具有64个CPU的系统上,该数字的范围可以是0到63。
范围以M- 形式给出 N,其中 M小于或等于 N并且两个数字都在CPU范围内。
如果CPU号是允许范围之外的整数或不是整数,则会发生错误。
VCPU说明符 示例(它们都是等效的):
VCPU = 0,1,2,3,9,10
VCPU = 0-3,9-10
VCPU = 9,10,0-3
VCPU = 0,10,1,9,3,2
该THREAD_PRIORITY属性指示分配给该组的线程的优先级:
如果THREAD_PRIORITY未指定,则默认优先级为0。
如果THREAD_PRIORITY给出,则属性值必须在-20(最高优先级)到19(最低优先级)之间。系统资源组的优先级必须在-20到0的范围内。用户资源组的优先级必须在0到19的范围内。对系统和用户组使用不同的范围可以确保用户线程永远不会拥有更高的优先级。优先级高于系统线程。
ENABLE并DISABLE指定最初启用或禁用资源组。如果两者均未指定,则默认情况下启用该组。禁用的组不能为其分配线程。
例子:
创建具有单个CPU和最低优先级的已启用用户组:
CREATE RESOURCE GROUP rg1
TYPE = USER
VCPU = 0
THREAD_PRIORITY = 19;
创建一个禁用的系统组,该组没有CPU关联(可以使用所有CPU)并且具有最高优先级:
CREATE RESOURCE GROUP rg2
TYPE = SYSTEM
THREAD_PRIORITY = -20
DISABLE;
资源组管理对于发生它的服务器是本地的。CREATE RESOURCE GROUP 语句不会写入二进制日志,也不会被复制。
ALTER RESOURCE GROUP修改现有组:、
ALTER RESOURCE GROUP说明
ALTER RESOURCE GROUP group_name
[VCPU [=] vcpu_spec [, vcpu_spec] ...]
[THREAD_PRIORITY [=] N]
[ENABLE|DISABLE [FORCE]]
vcpu_spec: {N | M - N}
ALTER RESOURCE GROUP用于资源组管理(请参见 第5.1.15节“资源组”)。该语句更改现有资源组的可修改属性。它需要RESOURCE_GROUP_ADMIN 特权。
group_name标识要更改的资源组。如果该组不存在,则会发生错误。
可以使用修改CPU亲和力,优先级以及是否启用该组的属性ALTER RESOURCE GROUP。这些属性的指定方法与描述方法相同CREATE RESOURCE GROUP(请参见第13.7.2.2节“ CREATE RESOURCE GROUP语句”)。仅指定的属性被更改。未指定的属性保留其当前值。
该FORCE改性剂使用 DISABLE。如果资源组分配了任何线程,它将确定语句的行为:
如果FORCE未给出,则组中的现有线程将继续运行直到终止,但是无法将新线程分配给该组。
如果FORCE指定,则该组中的现有线程将移至其各自的默认组(系统线程到SYS_default,用户线程到USR_default)。
名称和类型属性是在组创建时设置的,此后无法使用进行修改ALTER RESOURCE GROUP。
例子:
更改组CPU关联性:
ALTER RESOURCE GROUP rg1 VCPU = 0-63;
更改组线程优先级:
ALTER RESOURCE GROUP rg2 THREAD_PRIORITY = 5;
禁用组,将分配给它的所有线程移动到默认组:
ALTER RESOURCE GROUP rg3 DISABLE FORCE;
资源组管理对于发生它的服务器是本地的。ALTER RESOURCE GROUP 语句不会写入二进制日志,也不会被复制。
DROP RESOURCE GROUP删除现有组:
DROP RESOURCE GROUP语句
DROP RESOURCE GROUP group_name [FORCE]
DROP RESOURCE GROUP用于资源组管理(请参见 第5.1.15节“资源组”)。该语句删除资源组。它需要 RESOURCE_GROUP_ADMIN特权。
group_name标识要删除的资源组。如果该组不存在,则会发生错误。
该FORCE修改决定声明的行为,如果资源组具有分配给它的任何线程:
如果FORCE未给出,并且任何线程都分配给该组,则会发生错误。
如果FORCE指定,则该组中的现有线程将移至其各自的默认组(系统线程到SYS_default,用户线程到USR_default)。
例子:
删除一个组,如果该组包含任何线程,则失败:
DROP RESOURCE GROUP rg1;
删除一个组并将现有线程移至默认组:
DROP RESOURCE GROUP rg2 FORCE;
资源组管理对于发生它的服务器是本地的。DROP RESOURCE GROUP 语句不会写入二进制日志,也不会被复制。
这些语句需要 RESOURCE_GROUP_ADMIN特权。
要管理资源组分配,请使用以下功能:
SET RESOURCE GROUP将线程分配给一个组:
SET RESOURCE GROUP语句
SET RESOURCE GROUP group_name
[FOR thread_id [, thread_id] ...]
SET RESOURCE GROUP用于资源组管理(请参见 第5.1.15节“资源组”)。该语句将线程分配给资源组。它需要 RESOURCE_GROUP_ADMIN或 RESOURCE_GROUP_USER特权。
group_name标识要分配的资源组。任何thread_id 值都表示要分配给该组的线程。可以从“性能模式” threads表中确定线程ID 。如果资源组或任何命名线程ID不存在,则会发生错误。
如果没有no FOR子句,该语句会将会话的当前线程分配给资源组。
该FOR语句使用命名线程ID 的子句将这些线程分配给资源组。
对于试图将系统线程分配给用户资源组或将用户线程分配给系统资源组的尝试,会发生警告。
例子:
将当前会话线程分配给一个组:
SET RESOURCE GROUP rg1;
将命名线程分配给组:
SET RESOURCE GROUP rg2 FOR 14, 78, 4;
资源组管理对于发生它的服务器是本地的。SET RESOURCE GROUP 语句不会写入二进制日志,也不会被复制。
另一种选择SET RESOURCE GROUP是 RESOURCE_GROUP优化器提示,该提示将单个语句分配给资源组
该RESOURCE_GROUP 优化程序提示指定单个语句的一组:
请参见 第8.9.3节“优化器提示”。
这些操作需要 RESOURCE_GROUP_ADMIN或 RESOURCE_GROUP_USER特权。
资源组定义存储在 resource_groups数据字典表中,以便组在服务器重新启动后持久存在。因为 resource_groups它是数据字典的一部分,所以用户无法直接访问它。使用INFORMATION_SCHEMA.RESOURCE_GROUPS 表可获得资源组信息,该 表实现为数据字典表上的视图。请参见 第25.25节“ 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;
资源组复制
资源组管理对于发生它的服务器是本地的。资源组SQL语句和对resource_groups数据字典表的修改 不会写入二进制日志,也不会被复制。
资源组限制
在某些平台或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和Ambient Capabilities支持内核的Linux平台(Linux 4.3或更高版本)上,建议的启用CAP_SYS_NICE能力的方法是修改MySQL服务文件,并保持 mysqld二进制不变。要为MySQL调整服务文件,请使用以下过程:
运行适合您平台的命令:
Oracle Linux,Red Hat和Fedora系统:
shell> sudo systemctl edit mysqld
SUSE,Ubuntu和Debian系统:
shell> sudo systemctl edit mysql
使用编辑器,将以下文本添加到服务文件:
[Service]
AmbientCapabilities=CAP_SYS_NICE
重新启动MySQL服务。
如果您不能如上所述启用该CAP_SYS_NICE 功能,则可以使用setcap命令手动设置该功能,并指定mysqld可执行文件的路径名(这需要sudo访问)。您可以使用getcap检查功能。例如:
shell> sudo setcap cap_sys_nice+ep /path/to/mysqld
shell> getcap /path/to/mysqld
/path/to/mysqld = cap_sys_nice+ep
为了安全起见,请将mysqld二进制文件的执行限制 为该 root用户和具有mysql组成员身份的用户 :
shell> sudo chown root:mysql /path/to/mysqld
shell> sudo chmod 0750 /path/to/mysqld
重要
如果需要手动使用setcap,则必须在每次重新安装后执行。
在Windows上,线程以五个线程优先级之一运行。下表列出了资源组线程优先级范围-20到19映射到那些级别。
表5.5 Windows上的资源组线程优先级





