Aru*_*ath 4 sql-server resource-governor sql-server-2014
我正在尝试设置资源调控器,以限制使用 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
Run Code Online (Sandbox Code Playgroud)
资源调控器分类器功能仅在登录过程中运行。模拟通过EXECUTE AS
不会触发分类器功能。 EXECUTE AS
是 SQL Server 代理在另一个登录名或用户的上下文中运行作业的方式。
指定Run As ...
用户或修改Job Owner
不会改变 SQL Server 代理登录到 SQL Server 的方式。让 SQL Server 代理作业在特定资源组中运行的唯一方法是将 SQL Server 代理服务帐户放入它自己的资源组中。
由于测试是了解实际情况的好方法,因此我创建了一个小型测试平台。不要在生产系统上运行它,因为它会修改资源组配置。
这将创建分类器函数,以及附加到测试资源池的几个资源组:
USE master;
SET NOCOUNT ON;
GO
CREATE FUNCTION dbo.fnDummyClassifier()
RETURNS sysname
WITH SCHEMABINDING
AS
BEGIN
DECLARE @GroupName sysname = NULL;
IF SUSER_SNAME() = 'DOMAIN\USER'
SET @GroupName = N'AgentServiceAccountGroup';
IF SUSER_SNAME() = 'ResourceGovernorTestLogin'
SET @GroupName = N'ResourceGovernorTestLoginGroup';
IF SUSER_SNAME() = 'ResourceGovernorTestUser'
SET @GroupName = N'ResourceGovernorTestUserGroup';
IF @GroupName IS NULL
SET @GroupName = N'default';
RETURN @GroupName;
END
GO
CREATE RESOURCE POOL TestPool
WITH (MAX_CPU_PERCENT = 10);
CREATE WORKLOAD GROUP AgentServiceAccountGroup
WITH (
group_max_requests=0
, importance=Medium
, request_max_cpu_time_sec=0
, request_max_memory_grant_percent=25
, request_memory_grant_timeout_sec=0
, max_dop=0
)
USING TestPool;
CREATE WORKLOAD GROUP ResourceGovernorTestLoginGroup
WITH (
group_max_requests=0
, importance=Medium
, request_max_cpu_time_sec=0
, request_max_memory_grant_percent=25
, request_memory_grant_timeout_sec=0
, max_dop=0
)
USING TestPool;
CREATE WORKLOAD GROUP ResourceGovernorTestUserGroup
WITH (
group_max_requests=0
, importance=Medium
, request_max_cpu_time_sec=0
, request_max_memory_grant_percent=25
, request_memory_grant_timeout_sec=0
, max_dop=0
)
USING TestPool;
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = [dbo].[fnDummyClassifier]);
ALTER RESOURCE GOVERNOR RECONFIGURE;
GO
Run Code Online (Sandbox Code Playgroud)
在这里,我们将创建一个登录名,并允许它登录,VIEW SERVER STATE
这样我们就可以知道会话已分配给哪个资源组。
CREATE LOGIN ResourceGovernorTestLogin
WITH PASSWORD = '!NnrtiHummusPlenumPoodle2'
, DEFAULT_LANGUAGE = us_english
, CHECK_EXPIRATION = OFF
, CHECK_POLICY = OFF;
GRANT VIEW SERVER STATE TO ResourceGovernorTestLogin;
GO
Run Code Online (Sandbox Code Playgroud)
这将创建一个 SQL Server 代理作业,其中“所有者”设置为我们刚刚创建的登录名。由于登录名不是 sysadmin 的成员,SQL Server 代理将在该登录名的上下文中运行此作业。
DECLARE @JobID uniqueidentifier;
EXEC msdb.dbo.sp_add_job @job_name = 'TestResourceGovernorJob'
, @enabled = 1
, @description = 'Tests resource governor classification'
, @start_step_id = 1
, @owner_login_name = 'ResourceGovernorTestLogin'
, @job_id = @JobID OUTPUT;
EXEC msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 1, @step_name = 'Step1'
, @subsystem = 'TSQL'
, @command = 'SELECT '''';
SELECT UserName = CONVERT(nvarchar(30), SUSER_SNAME())
, [SYSTEM_USER] = CONVERT(nvarchar(30), SYSTEM_USER)
, [SESSION_USER] = CONVERT(nvarchar(30), SESSION_USER)
, [ORIGINAL_LOGIN] = CONVERT(nvarchar(30), ORIGINAL_LOGIN())
, WorkloadGroup = CONVERT(nvarchar(30), wg.name)
FROM sys.dm_exec_requests der
INNER JOIN sys.dm_resource_governor_workload_groups wg ON der.group_id = wg.group_id
WHERE der.session_id = @@SPID;'
, @flags = 4 --write step output into msdb.dbo.sysjobstephistory
, @on_success_action = 1;
EXEC msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(LOCAL)';
/*
Call SQL Server Agent via msdb.dbo.sp_notify_job
which in turn calls msdb.dbo.xp_notify_job.
The SQL Server Agent executable logs into the
SQL Server instance using the service account,
then performs an "EXECUTE AS ..." to run
job step(s).
*/
EXEC msdb.dbo.sp_start_job @job_id = @JobID;
GO
WAITFOR DELAY N'00:00:01';
DECLARE @msg nvarchar(max);
SELECT @msg = sjh.message
FROM msdb.dbo.sysjobhistory sjh
INNER JOIN msdb.dbo.sysjobs sj ON sjh.job_id = sj.job_id
WHERE sj.name = 'TestResourceGovernorJob'
AND sjh.step_id = 1;
PRINT (N'');
PRINT (@msg);
PRINT (N'');
EXEC msdb.dbo.sp_delete_job @job_name = 'TestResourceGovernorJob';
GO
Run Code Online (Sandbox Code Playgroud)
来自上述作业的 msdb 历史记录表的结果:
作业“TestResourceGovernorJob”成功启动。 以用户身份执行:ResourceGovernorTestLogin。 —— (1 行受影响) 用户名 SYSTEM_USER SESSION_USER ORIGINAL_LOGIN WorkloadGroup ------------------------------ --------------------- ---------- ------------------------------ ---------- -------------------- ------------------------------ ResourceGovernorTestLogin ResourceGovernorTestLogin 来宾 DOMAIN\USER AgentServiceAccountGroup (受影响的 1 行)。步骤成功了。
接下来,我们将为登录创建一个用户,并使用Run As
SQL Server 作业步骤的高级属性中的选项运行新版本的作业。
CREATE USER ResourceGovernorTestUser
FOR LOGIN ResourceGovernorTestLogin;
DECLARE @JobID uniqueidentifier;
EXEC msdb.dbo.sp_add_job @job_name = 'TestResourceGovernorJob'
, @enabled = 1
, @description = 'Tests resource governor classification'
, @start_step_id = 1
, @owner_login_name = 'ResourceGovernorTestLogin'
, @job_id = @JobID OUTPUT;
EXEC msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 1, @step_name = 'Step1'
, @subsystem = 'TSQL'
, @database_name = 'master'
, @database_user_name = 'ResourceGovernorTestUser'
, @command = 'SELECT '''';
SELECT UserName = CONVERT(nvarchar(30), SUSER_SNAME())
, [SYSTEM_USER] = CONVERT(nvarchar(30), SYSTEM_USER)
, [SESSION_USER] = CONVERT(nvarchar(30), SESSION_USER)
, [ORIGINAL_LOGIN] = CONVERT(nvarchar(30), ORIGINAL_LOGIN())
, WorkloadGroup = CONVERT(nvarchar(30), wg.name)
FROM sys.dm_exec_requests der
INNER JOIN sys.dm_resource_governor_workload_groups wg ON der.group_id = wg.group_id
WHERE der.session_id = @@SPID;'
, @flags = 4 --write step output into msdb.dbo.sysjobstephistory
, @on_success_action = 1;
EXEC msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(LOCAL)';
/*
Call SQL Server Agent via msdb.dbo.sp_notify_job
which in turn calls msdb.dbo.xp_notify_job.
The SQL Server Agent executable logs into the
SQL Server instance using the service account,
then performs an "EXECUTE AS ..." to run
job step(s).
*/
EXEC msdb.dbo.sp_start_job @job_id = @JobID;
GO
WAITFOR DELAY N'00:00:01';
DECLARE @msg nvarchar(max);
SELECT @msg = sjh.message
FROM msdb.dbo.sysjobhistory sjh
INNER JOIN msdb.dbo.sysjobs sj ON sjh.job_id = sj.job_id
WHERE sj.name = 'TestResourceGovernorJob'
AND sjh.step_id = 1;
PRINT (N'');
PRINT (@msg);
PRINT (N'');
EXEC msdb.dbo.sp_delete_job @job_name = 'TestResourceGovernorJob';
DROP USER ResourceGovernorTestUser;
GO
Run Code Online (Sandbox Code Playgroud)
作业运行的输出:
作业“TestResourceGovernorJob”成功启动。 以用户身份执行:ResourceGovernorTestLogin。 —— (1 行受影响) 用户名 SYSTEM_USER SESSION_USER ORIGINAL_LOGIN WorkloadGroup ------------------------------ --------------------- ---------- ------------------------------ ---------- -------------------- ------------------------------ ResourceGovernorTestLogin ResourceGovernorTestLogin ResourceGovernorTestUser DOMAIN\USER AgentServiceAccountGroup (受影响的 1 行)。步骤成功了。
这会清理资源调控器配置,并删除分类器功能和登录。
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = NULL);
DROP WORKLOAD GROUP AgentServiceAccountGroup;
DROP WORKLOAD GROUP ResourceGovernorTestUserGroup;
DROP WORKLOAD GROUP ResourceGovernorTestLoginGroup;
DROP RESOURCE POOL TestPool;
ALTER RESOURCE GOVERNOR RECONFIGURE;
DROP FUNCTION dbo.fnDummyClassifier
DROP LOGIN ResourceGovernorTestLogin;
GO
Run Code Online (Sandbox Code Playgroud)
在上面的两个结果集中,您可以看到资源调控器分类器函数将每个作业放入AgentServiceAccountGroup
组中;这是因为 SQL Server 代理最初使用 SQL Server 代理启动时使用的服务帐户登录到 SQL Server。
归档时间: |
|
查看次数: |
1340 次 |
最近记录: |