使用 MySQL 资源组管理 CPU 分配

本文档介绍了如何在 Cloud SQL for MySQL 中配置和使用 MySQL 资源组,以管理和优先处理不同的数据处理需求所对应的 CPU 资源分配。

概览

MySQL 资源组是 MySQL 8.0 中引入的一项功能,可让您管理单个数据库实例上运行的不同线程之间的 CPU 资源分配并确定其优先级。这有助于缓解“嘈杂邻居”问题,即低优先级任务(例如每日分析或批量报告)可能会导致 CPU 使用率飙升,从而降低关键的高优先级客户端连接(例如在线交易处理 [OLTP])的性能。

所有 Cloud SQL for MySQL 8.0 及更高版本实例(包括 Cloud SQL 企业版和 Cloud SQL 企业 Plus 版)均支持资源组。

社区 MySQL 与 Cloud SQL 资源组之间的区别

Cloud SQL for MySQL 是一项全代管式服务。为了帮助确保实例可靠性并保护 Cloud SQL 的内部进程,与社区 MySQL 行为相比,Cloud SQL 存在以下差异和限制:

不支持 CPU 核心亲和性

不支持指定核心级 CPU 固定。例如,在 Cloud SQL for MySQL 中创建资源组时,您无法指定 VCPU = 2-3VCPU = 0。由于底层虚拟机的核心拓扑已抽象化,因此在 CREATE RESOURCE GROUPALTER RESOURCE GROUP 语句中尝试使用 VCPU 子句都会失败,并显示以下访问遭拒错误。

ERROR 1227 (42000): Access denied; This operation (CPU clause) is not allowed on the Cloud SQL environment. Only THREAD_PRIORITY allowed;

禁止使用的系统资源组

Cloud SQL 不支持创建系统资源组。仅允许使用用户级资源组 (TYPE = USER),线程优先级范围为 0(最高用户优先级)到 19(最低用户优先级)。

禁止使用系统资源组,以防止用户工作负载使关键 Cloud SQL 后台作业(例如备份、监控和复制)资源不足。

使用 TYPE = SYSTEM 运行 CREATE RESOURCE GROUP 命令会失败,并显示以下错误:

ERROR 1227 (42000): Access denied; This operation (TYPE=SYSTEM) is not allowed on the Cloud SQL environment. Only TYPE=USER is allowed;

自动进行二进制日志记录和资源组 DDL 复制

在社区版 MySQL 中,资源组操作(例如 CREATEALTERDROP RESOURCE GROUP)永远不会写入二进制日志。Cloud SQL 会替换此默认行为,以便将所有资源组定义命令写入二进制日志。

这样可确保资源组自动复制到只读副本,从而让您能够在副本上使用查询优化器提示(或 RESOURCE_GROUP 提示),以避免因缺少组而导致查询失败。组定义也会捕获到二进制日志流中,以用于时间点恢复 (PITR)。

线程会话分配(例如 SET RESOURCE GROUP)不会写入二进制日志。

已向 cloudsqlsuperuser 授予管理员权限

如需使用资源组,您需要以下管理数据库权限:

  • RESOURCE_GROUP_ADMIN: 创建、更改和删除资源组
  • RESOURCE_GROUP_USER:分配线程或在查询中使用提示

在 Cloud SQL 中,默认情况下会向 cloudsqlsuperuser 角色授予这两项权限。

MySQL 管理员还可以向其他用户授予 RESOURCE_GROUP_USERRESOURCE_GROUP_ADMIN 数据库权限。

在 Cloud SQL 中管理资源组

您可以在 Cloud SQL 中配置和管理用户级资源组,以优化数据库中的资源分配。这样一来,您就可以控制和优先分配实例上各种数据库会话工作负载的 CPU 资源。

如需详细了解 MySQL 资源组配置和参考行为,请参阅 MySQL 文档中的资源组

如需在 Cloud SQL 中管理资源组,您可以执行以下操作:

准备工作

在创建资源组之前,请验证以下内容:

  • 您已使用具有 RESOURCE_GROUP_ADMIN 权限的用户账号登录数据库。默认的 root 用户以及分配有 cloudsqlsuperuser 角色的任何数据库账号默认都具有此权限。

  • 您的 Cloud SQL 实例运行的是 MySQL 8.0 或更高版本。

创建资源组

创建线程优先级介于 0(最高优先级)和 19(最低优先级)之间的用户级资源组。标准连接的默认线程优先级为 0

如需创建资源组,请运行以下语句:

CREATE RESOURCE GROUP GROUP_NAME
  TYPE = USER
  THREAD_PRIORITY = PRIORITY_VALUE;

替换以下内容:

  • GROUP_NAME:您要创建的资源组的名称。
  • PRIORITY_VALUE:资源组的 CPU 调度优先级,从 0(最高优先级)到 19(最低优先级)。

修改资源组的优先级

如需修改现有资源组的 CPU 调度优先级,请运行以下语句:

ALTER RESOURCE GROUP GROUP_NAME
  THREAD_PRIORITY = PRIORITY_VALUE;

替换以下内容:

  • GROUP_NAME:您要修改的资源组的名称。
  • PRIORITY_VALUE:新的 CPU 调度优先级。

删除资源组

如需舍弃资源组,请运行以下语句:

DROP RESOURCE GROUP GROUP_NAME;

替换以下内容:

  • GROUP_NAME:您要舍弃的资源组的名称。

将连接和查询分配给资源组

如需对工作负载强制执行资源限制,请将有效连接或特定查询分配给用户资源组。

如需将会话连接分配给群组,请执行以下操作:

  1. 向工作负载用户授予权限:

    GRANT RESOURCE_GROUP_USER ON *.* TO 'USERNAME'@'%';

    替换以下内容:

    • USERNAME:您要向其授予特权的数据库用户。
  2. 当用户连接时,运行:

    SET RESOURCE GROUP GROUP_NAME;

    替换以下内容:

    • GROUP_NAME:您要将连接分配到的资源组的名称。

    或者指定特定线程 ID:

    SET RESOURCE GROUP GROUP_NAME FOR THREAD_ID;

    替换以下内容:

    • GROUP_NAME:您要将连接分配到的资源组的名称。
    • THREAD_ID:您要分配的特定数据库线程的 ID。

如需通过优化器提示将单个查询分配给某个组,请执行以下操作:

在 DML 或 SELECT 语句中使用 RESOURCE_GROUP 优化器注释提示:

SELECT /*+ RESOURCE_GROUP(GROUP_NAME) */
  COLUMN_NAME_1,
  SUM(COLUMN_NAME_2)
FROM TABLE_NAME
GROUP BY COLUMN_NAME_1;

替换以下内容:

  • GROUP_NAME:您要运行查询的资源组的名称。
  • COLUMN_NAME_1:您要按哪个列对结果进行分组。
  • COLUMN_NAME_2:要计算总和的列值。
  • TABLE_NAME:您要查询的表。

监控资源组

如需检查已配置的资源组,请执行以下操作:

SELECT * FROM INFORMATION_SCHEMA.RESOURCE_GROUPS;

如需查看活跃的连接线程及其分配的资源组,请运行以下查询:

SELECT THREAD_ID, NAME, TYPE, RESOURCE_GROUP
  FROM performance_schema.threads;

后续步骤