Resource Governor 分类器函数
资源调控器分类过程可以使用分类器函数将传入会话分配给工作负荷组。 分类器函数包含用于将会话分类为工作负荷组的自定义逻辑。
有关配置和监视示例以及了解资源调控器最佳做法,请参阅 教程:资源调控器配置示例和最佳做法。
分类
使用资源调控器时,每个新会话都分类为工作负荷组。 分类器是你创建的标量用户定义函数。 它包含您所期望的逻辑,以便将传入会话分配给工作负荷组。 分类器所返回的标量值是用来分配给传入会话的工作负荷组的标识。
如果启用了资源调控器,并在资源调控器配置中指定了分类器函数,则函数输出将确定用于新会话的工作负荷组。 否则,所有用户会话将分类为 default
工作负荷组。
注意
internal
工作负荷组仅用于内部系统请求。 不能更改用于将请求分配到 internal
工作负荷组的条件,并且无法将请求显式分类到 internal
工作负荷组中。
必须完成以下步骤才能开始使用分类器函数:
- 使用 CREATE FUNCTION在
master
数据库中创建函数。 该函数必须使用架构绑定。 - 使用 ALTER RESOURCE GOVERNOR 和
CLASSIFIER_FUNCTION
参数引用 Resource Governor 配置中的函数。 - 使用
ALTER RESOURCE GOVERNOR RECONFIGURE
使新配置生效。
重要
如果分类器函数未在客户端配置的连接超时期限内完成,客户端连接尝试可能会超时。 请务必创建分类器函数,这些分类器函数在发生连接超时之前完成执行。
使分类器函数保持简单。 避免使用复杂或耗时的逻辑。 如果可能,请避免在分类器中访问数据。
分类器函数具有以下特征和行为:
- 函数在服务器范围(
master
数据库中)中定义。 - 该函数使用架构绑定定义。 有关详细信息,请参阅 SCHEMABINDING。
- 将针对每个新会话评估函数,即使在启用了连接池的情况下也会这样做。
- 该函数返回会话的工作负荷组上下文。 会话分配给分类器在会话生存期内返回的工作负载组。
- 如果函数返回
NULL
、default
或不存在的工作负荷组的名称,则会为会话提供default
工作负荷组上下文。 如果由于任何原因而导致函数失败,则会话也将拥有default
上下文。 - 使用
ALTER RESOURCE GOVERNOR (WITH CLASSIFIER_FUNCTION = ...)
语句添加或删除分类器函数后,更改仅在执行ALTER RESOURCE GOVERNOR RECONFIGURE
语句后生效。 - 一次只能将一个函数指定为分类器。
- 除非使用将函数名称设置为
NULL
或另一个函数名称的ALTER RESOURCE GOVERNOR (WITH CLASSIFIER_FUNCTION = ...)
语句删除分类器状态,否则无法修改或删除分类器函数。 - 如果没有分类器函数,所有会话都分类为
default
组。 - 分类器函数输出中指定的工作负荷组超出了架构绑定限制的范围。 例如,不能删除分类器函数中引用的表,但即使分类器返回该组的名称,也可以删除工作负荷组。
启用 DAC
出于故障排除和诊断目的,我们建议主动启用并熟悉专用管理员连接(DAC)。 DAC 不受资源调控器分类的约束。 即使资源调控器配置出现故障并且使其他连接不可用,也可以使用 DAC 来监视和排查分类器函数问题。 有关详细信息,请参阅数据库管理员的诊断连接。
如果无法使用 DAC 进行故障排除,可以以单用户模式启动服务器。 虽然单用户模式连接不受分类限制,但在它运行时,你无法诊断 Resource Governor 分类。
在单用户模式下使用 DAC 或连接进行连接后,可以修改 Resource Governor 配置,以删除故障分类器函数或禁用 Resource Governor。
登录过程
在资源调控器上下文中,会话的登录过程包括以下步骤:
- 登录身份验证。
- 登录触发器执行。 仅当实例中存在登录触发器时发生。
- 分类。
分类开始时,资源调控器执行分类器函数,并使用函数返回的标量值将请求发送到匹配的工作负荷组。
可以使用 sys.dm_exec_sessions 和 sys.dm_exec_requests 系统视图监视登录触发器和分类器函数的执行。
例子
资源调控器分类器函数可以使用各种自定义逻辑。 有关更多示例和演练,请参阅 教程:资源调控器配置示例和最佳做法。
A. 主机名
此函数使用 HOST_NAME() 内置系统函数将特定主机名中的会话分类为名为 Reports
的工作负荷组。 所有其他会话将继续分类为 default
工作负荷组。
CREATE FUNCTION dbo.rg_classifier()
RETURNS sysname
WITH SCHEMABINDING
AS
BEGIN
DECLARE @grp_name sysname = 'default';
IF (HOST_NAME() IN ('reportserver1','reportserver2'))
SET @grp_name = 'Reports';
RETURN @grp_name;
END;
GO
B. 用户名
此函数使用 SUSER_SNAME() 内置系统函数将特定用户名或服务帐户名称中的会话分类为名为 Reports
的工作负荷组。 所有其他会话将继续分类为 default
工作负荷组。
CREATE FUNCTION dbo.rg_classifier()
RETURNS sysname
WITH SCHEMABINDING
AS
BEGIN
DECLARE @grp_name sysname = 'default';
IF (SUSER_SNAME() IN ('Reporting', 'domain/svc_reporting'))
SET @grp_name = 'Reports';
RETURN @grp_name;
END;
GO
C. 应用程序名称
此函数使用 APP_NAME() 内置系统函数将特定应用程序名称中的会话分类为名为 Adhoc
的工作负荷组。 所有其他会话将继续分类为 default
工作负荷组。
重要
应用程序或用户可以提供任何应用程序名称作为连接字符串的一部分。 用户可以通过各种应用程序进行连接。
CREATE FUNCTION dbo.rg_classifier()
RETURNS sysname
WITH SCHEMABINDING
AS
BEGIN
DECLARE @grp_name sysname = 'default';
IF (APP_NAME() IN ('Microsoft SQL Server Management Studio - Query','azdata'))
SET @grp_name = 'Adhoc';
RETURN @grp_name;
END;
GO