

# 对 RDS for SQL Server 实例使用 Microsoft SQL Server 资源调控器
<a name="ResourceGovernor.Using"></a>

在将资源调控器选项添加到选项组后，资源调控器尚未在数据库引擎级别处于活动状态。要完全启用资源调控器，必须使用 RDS for SQL Server 存储过程启用它，并创建所需的资源调控器对象。有关更多信息，请参阅 [连接到 Microsoft SQL Server 数据库实例](USER_ConnectToMicrosoftSQLServerInstance.md)。

首先，连接到 SQL Server 数据库，然后调用相应的 RDS for SQL Server 存储过程以完成配置。有关连接到数据库的说明，请参阅 [连接到 Microsoft SQL Server 数据库实例](USER_ConnectToMicrosoftSQLServerInstance.md)。

有关如何调用每个存储过程的说明，请参阅以下主题：

**Topics**
+ [管理资源池](#ResourceGovernor.ManageResourcePool)
+ [管理工作负载组](#ResourceGovernor.ManageWorkloadGroups)
+ [创建并注册分类器函数](#ResourceGovernor.ClassifierFunction)
+ [删除分类器函数](#ResourceGovernor.DropClassifier)
+ [注销分类器函数](#ResourceGovernor.DeregisterClassifier)
+ [重置统计数据](#ResourceGovernor.ResetStats)
+ [资源调控器配置更改](#ResourceGovernor.ConfigChanges)
+ [将 TempDB 绑定到资源池](#ResourceGovernor.BindTempDB)
+ [解除 TempDB 与资源池的绑定](#ResourceGovernor.UnbindTempDB)
+ [清理资源调控器](#ResourceGovernor.Cleanup)

## 管理资源池
<a name="ResourceGovernor.ManageResourcePool"></a>

### 创建资源池
<a name="ResourceGovernor.CreateResourcePool"></a>

一旦在选项组上启用了资源调控器，您就可以使用 `rds_create_resource_pool` 创建自定义资源池。这些池可让您将特定百分比的 CPU、内存和 IOPS 分配给不同的工作负载。

**用法**

```
USE [msdb]
EXEC dbo.rds_create_resource_pool    
    @pool_name=value,
    @MAX_CPU_PERCENT=value,
    @CAP_CPU_PERCENT=value,
    @MAX_MEMORY_PERCENT=value,
    @MAX_IOPS_PER_VOLUME=value
```

以下参数为必需参数：
+ `@group_name`：是现有的用户定义工作负载组的名称。
+ `@pool_name`：是资源池的用户定义名称。*pool\$1name* 是字母数字，最多可包含 128 个字符，在数据库引擎实例中必须是唯一的，并且必须符合数据库标识符规则。

以下参数可选：
+ `@MAX_CPU_PERCENT`：指定在出现 CPU 争用时，资源池中的所有请求可获得的最大平均 CPU 带宽。*value* 是一个整数，默认设置为 100。支持的 *value* 范围介于 1 到 100 之间。
+ `@CAP_CPU_PERCENT`：指定资源池中的所有请求可获得的 CPU 带宽的硬上限。将最大 CPU 带宽级别限制为与指定的值相同。*value* 是一个整数，默认设置为 100。支持的 *value* 范围介于 1 到 100 之间。
+ `@MAX_MEMORY_PERCENT`：指定此资源池中的请求可以使用的最大查询工作区内存量。*value* 是一个整数，默认设置为 100。支持的 *value* 范围介于 1 到 100 之间。
+ `@MAX_IOPS_PER_VOLUME`：指定支持用于资源池的每个磁盘卷的最大每秒 I/O 操作数（IOPS）。支持的 *value* 范围介于 0 到 2^31-1（2147483647）之间。指定 0 可移除池的 IOPS 限制。默认值是 0。

**示例**

使用所有默认值创建资源池的示例：

```
--This creates resource pool 'SalesPool' with all default values
USE [msdb]
EXEC rds_create_resource_pool @pool_name = 'SalesPool';
     
--Apply changes
USE [msdb]
EXEC msdb.dbo.rds_alter_resource_governor_configuration;
     
--Validate configuration
select * from sys.resource_governor_resource_pools
```

使用指定的不同参数创建资源池的示例：

```
--creates resource pool
USE [msdb]
EXEC dbo.rds_create_resource_pool    
@pool_name='analytics',
@MAX_CPU_PERCENT = 30,
@CAP_CPU_PERCENT = 40,
@MAX_MEMORY_PERCENT = 20;
            
--Apply changes
EXEC msdb.dbo.rds_alter_resource_governor_configuration;
    
--Validate configuration
select * from sys.resource_governor_resource_pools
```

### 更改资源池
<a name="ResourceGovernor.AlterResourcePool"></a>

**用法**

```
USE [msdb]
EXEC dbo.rds_alter_resource_pool    
    @pool_name=value,
    @MAX_CPU_PERCENT=value,
    @CAP_CPU_PERCENT=value,
    @MAX_MEMORY_PERCENT=value,
    @MAX_IOPS_PER_VOLUME=value;
```

以下参数为必需参数：
+ `@pool_name`：是现有的用户定义资源池的名称。Amazon RDS SQL Server 不支持更改默认资源池。

至少必须指定其中一个可选参数：
+ `@MAX_CPU_PERCENT`：指定在出现 CPU 争用时，资源池中的所有请求可获得的最大平均 CPU 带宽。*value* 是一个整数，默认设置为 100。支持的 *value* 范围介于 1 到 100 之间。
+ `@CAP_CPU_PERCENT`：指定资源池中的所有请求可获得的 CPU 带宽的硬上限。将最大 CPU 带宽级别限制为与指定的值相同。*value* 是一个整数，默认设置为 100。支持的 *value* 范围介于 1 到 100 之间。
+ `@MAX_MEMORY_PERCENT`：指定此资源池中的请求可以使用的最大查询工作区内存量。*value* 是一个整数，默认设置为 100。支持的 *value* 范围介于 1 到 100 之间。
+ `@MAX_IOPS_PER_VOLUME`：指定支持用于资源池的每个磁盘卷的最大每秒 I/O 操作数（IOPS）。支持的 *value* 范围介于 0 到 2^31-1（2147483647）之间。指定 0 可移除池的 IOPS 限制。默认值是 0。

**示例**

```
--This alters resource pool
USE [msdb]
EXEC dbo.rds_alter_resource_pool    
    @pool_name='analytics',
    @MAX_CPU_PERCENT = 10,
    @CAP_CPU_PERCENT = 20,
    @MAX_MEMORY_PERCENT = 50;

--Apply changes
EXEC msdb.dbo.rds_alter_resource_governor_configuration;

--Validate configuration.
select * from sys.resource_governor_resource_pools
```

### 删除资源池
<a name="ResourceGovernor.DropResourcePool"></a>

**用法**

```
USE [msdb]
EXEC dbo.rds_drop_resource_pool    
@pool_name=value;
```

以下参数是必需参数：
+ `@pool_name`：是现有的用户定义资源池的名称。

**注意**  
SQL Server 不支持删除内部资源池或默认资源池。

**示例**

```
--This drops resource pool
USE [msdb]
EXEC dbo.rds_drop_resource_pool    
@pool_name='analytics'

--Apply changes
EXEC msdb.dbo.rds_alter_resource_governor_configuration;

--Validate configuration
select * from sys.resource_governor_resource_pools
```

## 管理工作负载组
<a name="ResourceGovernor.ManageWorkloadGroups"></a>

使用 `rds_create_workload_group` 和 `rds_alter_workload_group` 创建和管理的工作负载组支持您为查询组设置重要性级别、内存授予和其它参数。

### 创建工作负载组
<a name="ResourceGovernor.CreateWorkloadGroup"></a>

**用法**

```
USE [msdb]
EXEC dbo.rds_create_workload_group 
@group_name = value, 
@IMPORTANCE ={ LOW | MEDIUM | HIGH }, 
@REQUEST_MAX_MEMORY_GRANT_PERCENT =value, 
@REQUEST_MAX_CPU_TIME_SEC = value , 
@REQUEST_MEMORY_GRANT_TIMEOUT_SEC = value, 
@MAX_DOP = value, 
@GROUP_MAX_REQUESTS = value, 
@pool_name = value
```

以下参数为必需参数：
+ `@pool_name`：是现有的用户定义资源池的名称。
+ `@group_name`：是现有的用户定义工作负载组的名称。

以下参数可选：
+ `@IMPORTANCE`：指定请求在工作负载组中的相对重要性。默认值为 `MEDIUM`。
+ `@REQUEST_MAX_MEMORY_GRANT_PERCENT`：指定单个请求可以从池中占用的最大查询工作区内存量。*value* 是由 `MAX_MEMORY_PERCENT` 定义的资源池大小的百分比。默认值为 25。
+ `@REQUEST_MAX_CPU_TIME_SEC`：指定批处理请求可以使用的最大 CPU 时间量（秒）。*value* 必须为 0 或正整数。*value* 的默认设置为 0，这意味着无限制。
+ `@REQUEST_MEMORY_GRANT_TIMEOUT_SEC`：指定查询可以等待查询工作区内存中的内存授予变为可用的最长时间（秒）。*value* 必须为 0 或正整数。*value* 的默认设置为 0，此时使用基于查询成本的内部计算来确定最长时间。
+ `@MAX_DOP`：指定并行查询执行的最大并行度 (`MAXDOP`)。支持的 *value* 范围介于 0 到 64 之间。*value* 的默认设置为 0，此时使用全局设置。
+ `@GROUP_MAX_REQUESTS`：指定支持在工作负载组中同时执行的最大请求数。*value* 必须为 0 或正整数。*值*的默认设置为 0，支持无限制的请求。
+ `@pool_name` = 将工作负载组与由 *pool\$1name* 标识的用户定义资源池或 `default` 资源池相关联。如果未提供 *pool\$1name*，则工作负载组将与内置 `default` 池相关联。

**示例**

```
--This creates workload group named 'analytics'
USE msdb;
EXEC dbo.rds_create_workload_group 
    @group_name = 'analytics',
    @IMPORTANCE = 'HIGH',
    @REQUEST_MAX_MEMORY_GRANT_PERCENT = 25, 
    @REQUEST_MAX_CPU_TIME_SEC = 0, 
    @REQUEST_MEMORY_GRANT_TIMEOUT_SEC = 0, 
    @MAX_DOP = 0, 
    @GROUP_MAX_REQUESTS = 0, 
    @pool_name = 'analytics';

--Apply changes
EXEC msdb.dbo.rds_alter_resource_governor_configuration;
  
--Validate configuration
select * from sys.resource_governor_workload_groups
```

### 更改工作负载组
<a name="ResourceGovernor.AlterWorkloadGroup"></a>

**用法**

```
EXEC msdb.dbo.rds_alter_workload_group
    @group_name = value,
    @IMPORTANCE = 'LOW|MEDIUM|HIGH',
    @REQUEST_MAX_MEMORY_GRANT_PERCENT = value,
    @REQUEST_MAX_CPU_TIME_SEC = value,
    @REQUEST_MEMORY_GRANT_TIMEOUT_SEC = value,
    @MAX_DOP = value,
    @GROUP_MAX_REQUESTS = value,
    @pool_name = value
```

以下参数为必需参数：
+ `@group_name`：是默认工作负载组或现有的用户定义工作负载组的名称。

**注意**  
仅支持更改默认工作负载组上的 `REQUEST_MAX_MEMORY_GRANT_PERCENT` 参数。对于默认工作负载组，`REQUEST_MAX_MEMORY_GRANT_PERCENT` 必须介于 1 到 70 之间。在默认工作负载组中不能修改其它参数。可以在用户定义的工作负载组中修改所有参数。

以下参数可选：
+ `@IMPORTANCE`：指定请求在工作负载组中的相对重要性。默认值为 MEDIUM。
+ `@REQUEST_MAX_MEMORY_GRANT_PERCENT`：指定单个请求可以从池中占用的最大查询工作区内存量。*value* 是由 `MAX_MEMORY_PERCENT` 定义的资源池大小的百分比。默认值为 25。在 Amazon RDS 上，`REQUEST_MAX_MEMORY_GRANT_PERCENT` 必须介于 1 到 70 之间。
+ `@REQUEST_MAX_CPU_TIME_SEC`：指定批处理请求可以使用的最大 CPU 时间量（秒）。*value* 必须为 0 或正整数。*value* 的默认设置为 0，这意味着无限制。
+ `@REQUEST_MEMORY_GRANT_TIMEOUT_SEC`：指定查询可以等待查询工作区内存中的内存授予变为可用的最长时间（秒）。*value* 必须为 0 或正整数。*value* 的默认设置为 0，此时使用基于查询成本的内部计算来确定最长时间。
+ `@MAX_DOP`：指定并行查询执行的最大并行度（MAXDOP）。支持的 *value* 范围介于 0 到 64 之间。*value* 的默认设置为 0，此时使用全局设置。
+ `@GROUP_MAX_REQUESTS`：指定支持在工作负载组中同时执行的最大请求数。*value* 必须为 0 或正整数。*值*的默认设置为 0，支持无限制的请求。
+ `@pool_name`：将工作负载组与由 *pool\$1name* 标识的用户定义资源池相关联。

**示例**

修改默认工作负载组以更改 REQUEST\$1MAX\$1MEMORY\$1GRANT\$1PERCENT 的示例：

```
--Modify default workload group (set memory grant cap to 10%)
USE msdb
EXEC dbo.rds_alter_workload_group    
    @group_name = 'default',
    @REQUEST_MAX_MEMORY_GRANT_PERCENT=10;
    
--Apply changes
EXEC msdb.dbo.rds_alter_resource_governor_configuration;

--Validate configuration
SELECT * FROM sys.resource_governor_workload_groups WHERE name='default';
```

修改非默认工作负载组的示例：

```
EXEC msdb.dbo.rds_alter_workload_group    
    @group_name = 'analytics',
    @IMPORTANCE = 'HIGH',
    @REQUEST_MAX_MEMORY_GRANT_PERCENT = 30,
    @REQUEST_MAX_CPU_TIME_SEC = 3600,
    @REQUEST_MEMORY_GRANT_TIMEOUT_SEC = 60,
    @MAX_DOP = 4,
    @GROUP_MAX_REQUESTS = 100;

--Apply changes
EXEC msdb.dbo.rds_alter_resource_governor_configuration;
```

将非默认工作负载组移到另一个资源池的示例：

```
EXEC msdb.dbo.rds_alter_workload_group    
@group_name = 'analytics',
@pool_name='abc'

--Apply changes
EXEC msdb.dbo.rds_alter_resource_governor_configuration;

--Validate configuration
select * from sys.resource_governor_workload_groups
```

### 删除工作负载组
<a name="ResourceGovernor.DropWorkloadGroup"></a>

**用法**

```
EXEC msdb.dbo.rds_drop_workload_group    
@group_name = value
```

以下参数为必需参数：
+ `@group_name`：是现有的用户定义工作负载组的名称。

**示例**

```
--Drops a Workload Group:
EXEC msdb.dbo.rds_drop_workload_group    
@group_name = 'analytics';

--Apply changes
EXEC msdb.dbo.rds_alter_resource_governor_configuration;

--Validate configuration
select * from sys.resource_governor_workload_groups
```

## 创建并注册分类器函数
<a name="ResourceGovernor.ClassifierFunction"></a>

此过程在主数据库中创建资源调控器分类器函数，该函数根据指定的标准（用户名、数据库、主机或应用程序名称）将连接路由到自定义工作负载组。如果启用了资源调控器并在资源调控器配置中指定了分类器函数，则函数输出将决定用于新会话的工作负载组。在没有分类器函数的情况下，所有会话都归类到 `default` 组。

**设施特点：**
+ 支持多达两个工作负载组及其各自的路由条件。
+ 将标准与每个组内的 `AND` 条件相结合。
+ 每个工作负载组需要至少一个路由标准。
+ 函数名称必须以 `rg_classifier_` 开头。
+ 如果没有条件匹配，则使用默认组分配。

分类器函数具有以下特征和行为：
+ 该函数在服务器作用域（在主数据库中）中定义。
+ 该函数是通过架构绑定定义的。
+ 即使启用了连接池，也会为每个新会话评估该函数。
+ 该函数返回会话的工作负载组上下文。会话分配给分类器在会话生命周期内返回的工作负载组。
+ 如果函数返回 NULL、默认值或不存在的工作负载组的名称，则会话将获得默认的工作负载组上下文。如果函数因任何原因失败，也会为会话提供默认上下文。
+ 可以创建多个分类器函数。但是，SQL Server 支持一次只注册一个分类器函数。
+ 除非使用将函数名称设置为 NULL 的注销过程 (`EXEC dbo.msdb.rds_alter_resource_governor_configuration @deregister_function = 1;`) 来移除分类器状态，或者使用 (`EXEC dbo.msdb.rds_alter_resource_governor_configuration @classifier_function = <function_name>;`) 注册另一个分类器函数，否则无法删除分类器函数
+ 在没有分类器函数的情况下，所有会话都归类到默认组。
+ 在资源调控器配置中引用分类器函数时，您无法修改该函数。不过，您可以修改配置以使用不同的分类器函数。如果要对分类器进行更改，可以考虑创建一对分类器函数。例如，您可以创建 `rg_classifier_a` 和 `rg_classifier_b`。

**用法**

```
EXEC msdb.dbo.rds_create_classifier_function 
@function_name = value,
@workload_group1 = value, 
@user_name1 = value,
@db_name1 = value,
@host_name1 = value, 
@app_name1 = value, 
@workload_group2 = value,
@user_name2 = value,
@db_name2 = value,
@host_name2 = value,
@app_name2 = value
```

以下参数为必需参数：
+ `@function_name`：分类器函数的名称。必须以 `rg_classifier_` 开头
+ `@workload_group1`：第一个工作负载组的名称

以下参数可选：

（必须为组 1 指定其中至少一个标准）
+ `@user_name1`：组 1 的登录名
+ `@db_name1`：组 1 的数据库名称
+ `@host_name1`：组 1 的主机名
+ `@app_name1`：组 1 的应用程序名称

（如果指定组 2，则必须至少提供一个标准）
+ `@workload_group2`：第二个工作负载组的名称
+ `@user_name2`：组 2 的登录名
+ `@db_name2`：组 2 的数据库名称
+ `@host_name2`：组 2 的主机名
+ `@app_name2`：组 2 的应用程序名称

**注意**  
系统账户、数据库、应用程序和主机受到限制。

**示例**

一个工作负载组的基本示例：

```
/*Create a classifier to route all requests from 'PowerBI' app to workload group 
'reporting_group'*/

EXEC msdb.dbo.rds_create_classifier_function
@function_name = 'rg_classifier_a',
@workload_group1 = 'reporting_group',
@app_name1 = 'PowerBI';

--Register the classifier
EXEC msdb.dbo.rds_alter_resource_governor_configuration
@classifier_function = 'rg_classifier_a';

-- Apply changes
EXEC msdb.dbo.rds_alter_resource_governor_configuration

/*Query sys.resource_governor_configuration to validate that resource governor is enabled and is using the classifier function we created and registered*/

use master
go
SELECT OBJECT_SCHEMA_NAME(classifier_function_id) AS classifier_schema_name,
       OBJECT_NAME(classifier_function_id) AS classifier_object_name,
       is_enabled
FROM sys.resource_governor_configuration;
```

## 删除分类器函数
<a name="ResourceGovernor.DropClassifier"></a>

**用法**

```
USE [msdb]
EXEC dbo.rds_drop_classifier_function
@function_name = value;
```

以下参数是必需参数：
+ `@function_name`：是现有的用户定义分类器函数的名称

**示例**：

```
EXEC msdb.dbo.rds_drop_classifier_function
@function_name = 'rg_classifier_b';
```

## 注销分类器函数
<a name="ResourceGovernor.DeregisterClassifier"></a>

使用此过程可注销分类器函数。注销该函数后，新的会话将自动分配给默认工作负载组。

**用法**

```
USE [msdb]
EXEC dbo.rds_alter_resource_governor_configuration    
@deregister_function = 1;
```

要注销，需要使用以下参数：
+ `@deregister_function` 必须为 1

**示例**：

```
EXEC msdb.dbo.rds_alter_resource_governor_configuration 
    @deregister_function = 1;
GO

-- Apply changes
EXEC msdb.dbo.rds_alter_resource_governor_configuration;
```

## 重置统计数据
<a name="ResourceGovernor.ResetStats"></a>

资源调控器统计数据是自上次服务器重新启动以来的累积数据。如果您需要从特定时间开始收集统计数据，则可以使用以下 Amazon RDS 存储过程来重置统计数据。

**用法**

```
USE [msdb]
EXEC dbo.rds_alter_resource_governor_configuration  
@reset_statistics = 1;
```

要重置统计数据，需要使用以下参数：
+ `@reset_statistics` 必须为 1

## 资源调控器配置更改
<a name="ResourceGovernor.ConfigChanges"></a>

如果未启用资源调控器，则 `rds_alter_resource_governor_configuration` 启用资源调控器。启用资源调控器会产生以下结果：
+ 对新会话执行分类器函数（如果有），并将会话分配给工作负载组。
+ 在资源调控器配置中指定的资源限制将得到遵守和执行。
+ 在资源调控器配置中指定的资源限制将得到遵守和执行。
+ 在启用资源调控器之前存在的请求可能会受到启用资源调控器时所做的任何配置更改的影响。
+ 启用资源调控器之前的现有请求可能会受到启用资源调控器时所做的任何配置更改的影响。
+ 在 RDS for SQL Server 上，必须执行 `EXEC msdb.dbo.rds_alter_resource_governor_configuration` 才能使任何资源调控器配置更改生效。

**用法**

```
USE [msdb]
EXEC dbo.rds_alter_resource_governor_configuration
```

## 将 TempDB 绑定到资源池
<a name="ResourceGovernor.BindTempDB"></a>

在 Amazon RDS SQL Server 版本 2019 及更高版本中，您可以使用 `rds_bind_tempdb_metadata_to_resource_pool` 将 tempdb 内存优化型元数据绑定到特定的资源池。

**注意**  
在将 tempdb 元数据绑定到资源池之前，必须启用内存优化型 tempdb 元数据功能。要在 Amazon RDS 上启用此功能，需要使用静态参数 `tempdb metadata memory-optimized`。

在 Amazon RDS 上启用静态参数，并在不进行失效转移的情况下执行重启以使该参数生效：

```
aws rds modify-db-parameter-group \
    --db-parameter-group-name test-sqlserver-ee-2022 \
    --parameters "ParameterName='tempdb metadata memory-optimized',ParameterValue=True,ApplyMethod=pending-reboot"
```

**用法**

```
USE [msdb]
EXEC dbo.rds_bind_tempdb_metadata_to_resource_pool  
@pool_name=value;
```

以下参数是必需参数：
+ `@pool_name`：是现有的用户定义资源池的名称。

**注意**  
即使内存优化型 TempDB 元数据功能已启用，此更改也需要在不进行失效转移的情况下重启 sql 服务才能生效。

## 解除 TempDB 与资源池的绑定
<a name="ResourceGovernor.UnbindTempDB"></a>

从资源池中解除绑定 tempdb 内存优化型元数据。

**注意**  
此更改也要求在不进行失效转移的情况下重启 sql 服务才能生效

**用法**

```
USE [msdb]
EXEC dbo.rds_unbind_tempdb_metadata_from_resource_pool
```

## 清理资源调控器
<a name="ResourceGovernor.Cleanup"></a>

此过程将在您从选项组中移除资源调控器选项后，清理所有关联的对象。这将禁用资源调控器，将默认工作负载组恢复为默认设置，移除自定义工作负载组、资源池和分类器函数。

**主要特征**
+ 将默认工作负载组恢复为默认设置
+ 禁用资源调控器
+ 移除自定义工作负载组
+ 移除自定义资源池
+ 删除分类器函数
+ 如果启用，则移除 tempdb 资源池绑定

**重要**  
如果工作负载组上有活动的会话，则此清理可能会出错。要么等待活动的会话完成，要么根据您的业务要求终止活动的会话。建议在维护时段运行此操作。  
如果资源池已绑定到 tempdb，并且尚未在没有进行失效转移的情况下重启，则此清理可能会出错。如果您之前将资源池绑定到 tempdb 或解除了资源池与 tempdb 的绑定，请在不进行失效转移的情况下执行重启以使更改生效。建议在维护时段运行此操作。

**用法**

```
USE [msdb]
EXEC dbo.rds_cleanup_resource_governor
```