我正在尝试设置资源调控器以限制使用 SQL 代理作业运行的进程的 IOPS。分类器功能设置为识别特定登录名(使用该登录名运行的任何 spid 都应使用分配给它的资源组)。然后我EXECUTE AS LOGIN = 'ResourceGovernerUser'
在作业中添加,但我无法让它工作,它回退到默认池,因为作业是'EXECUTED AS 'ServiceAccount''
. 虽然如果我使用 来查看活动进程sp_WhoisActive
,登录名会显示为'ResourceGovernerUser'
而不是服务帐户。所以我修改了分类器函数以使用服务帐户,然后它就可以工作了。我使用 perfmon 计数器'Disk Read IO/Sec'
和对象'Disk Write IO/Sec'
下验证了这一点'Resource Pool Stats'
。
问题是 - 我如何让资源管理器使用服务帐户以外的登录名(与代理作业一起使用时)?我确实有一些未经测试的丑陋想法,例如 - 使用 CmdExec 或 PowerShell 代理运行作业。如果有人遇到类似情况或有更好的想法,我将不胜感激。谢谢你。
--Example Setup:
USE [master]
GO
CREATE RESOURCE POOL [SqlJobPool] WITH(
min_iops_per_volume=1,
max_iops_per_volume=5000);
GO
CREATE WORKLOAD GROUP [IOGroup]
USING [SqlJobPool];
GO
CREATE FUNCTION [dbo].[fn_LimitedIO]()
RETURNS SYSNAME WITH SCHEMABINDING
AS
BEGIN
DECLARE @grp SYSNAME;
IF SUSER_NAME() = N'ResourceGovernerUser' -- When this is set to the Service Account, it works
BEGIN
SET @grp = N'IOGroup';
END
ELSE
BEGIN
SET @grp = N'default';
END
RETURN @grp;
END
GO
ALTER RESOURCE GOVERNOR with (CLASSIFIER_FUNCTION = dbo.fn_LimitedIO);
ALTER RESOURCE GOVERNOR RECONFIGURE;
GO
--Within the Agent job
EXECUTE AS Login = 'ResourceGovernerUser'
EXECUTE SomeSQLStuff
资源调控器分类器函数仅在登录过程中运行。模拟通过
EXECUTE AS
不会触发分类器功能。EXECUTE AS
是 SQL Server 代理如何在另一个登录或用户的上下文中运行作业。指定
Run As ...
用户或修改用户Job Owner
不会改变 SQL Server 代理登录到 SQL Server 的方式。我可以使用仅查看用户名的分类器函数让 SQL Server 代理作业在特定资源组中运行的唯一方法是将 SQL Server 代理服务帐户放入它自己的资源组中。由于测试是了解实际情况的好方法,因此我创建了一个小型测试平台。不要在生产系统上运行它,因为它会修改资源组配置。
这将创建分类器函数,以及附加到测试资源池的几个资源组:
在这里,我们将创建一个登录名,并允许它这样做,
VIEW SERVER STATE
这样我们就可以知道会话已分配到哪个资源组。这将创建一个 SQL Server 代理作业,其中“所有者”设置为我们刚刚创建的登录名。由于登录不是 sysadmin 的成员,SQL Server 代理将在该登录的上下文中运行此作业。
上述作业的 msdb 历史记录表的结果:
接下来,我们将为登录创建一个用户,并使用
Run As
SQL Server 作业步骤的高级属性中的选项运行新版本的作业。该作业运行的输出:
这会清理资源管理器配置,并删除分类器功能和登录。
在上面的两个结果集中,您可以看到资源调控器分类器函数将每个作业放入
AgentServiceAccountGroup
组中;这是因为 SQL Server 代理最初使用 SQL Server 代理启动时使用的服务帐户登录到 SQL Server。