Hey guys!!
This time, I am bringing a very useful feature in administering SQL Server instances on shared servers (which have more than 1 instance), which is Resource Governor.
What is Resource Governor
View contentAn important note to note is that Resource Governor has gained a major upgrade from SQL Server 2014, which is also able to control and manage the I / O load of incoming requests, allowing you to limit the maximum amount of IOPS used to the certain profiles.
Not only can you determine maximum quantities, Resource Governor can also be used to set minimum amounts of resources that will be used by the profile (Pool) and ensure that these defined quantities are always available for these sessions.
Resource Governor is often used to limit certain database access profiles and to prevent sessions from different instances from having to contend for server resources with each other. Some examples where the use of Resource Governor can be implemented:
- limit maximum IOPS usage of ad-hoc user queries
- limit maximum CPU usage of instance jobs
- limit the maximum amount of memory used on a specific system
- limit the maximum IOPS usage of users who are part of a given AD group
- define the maximum amount of parallelism of queries for a given profile
How Resource Governor Works
View content- A new connection is created and a request is made by this session (1 Session of n).
- The session is classified according to the criteria predefined by the Classifier function. These criteria can be username, AD group to which it belongs, system role or database role to which it belongs, name of the software used, etc.
- The session request is routed to a workload group according to the return of the sort function, for example, 4 Group.
- The workload group uses the resource pool to which it is associated, for example, Pool 2.
- The resource pool provides and limits the resources required by the application, for example, 3 Application.
Reference: English - Portuguese
Classification Function
View contentThese functions will return the name of the workload group to be used by this new connection and from the logic implemented by it, which can use native functions in SQL Server such as HOST_NAME (), APP_NAME (), SUSER_NAME (), SUSER_SNAME (), IS_SRVROLEMEMBER () and IS_MEMBER () to determine criteria to classify the session and determined which workload group will be used when program_name like '% Management Studio%', for example.
For this reason, it is important to keep in mind that a poorly implemented or resource-intensive function to assign sessions can end up causing a major performance issue in the instance. For this reason, it is good practice to enable the ACD connection to allow connection in the instance bypassing the use of the classification function. If you do not do this and need
If you did not create a classification function, or did not assign the function to the Resource Governor or the function's return is “default”, NULL or the name of a group returned by the function does not exist, this session will be routed to the workload group "Default".
Note that only one sort function can be used by Resource Governor, and because the role is created using the WITH SCHEMABINDING parameter, it can only be removed or changed if you remove the role's association with Resource Governor using the command
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = NULL).
Creation Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
CREATE FUNCTION fncClassifica_ResourceGovernor() RETURNS SYSNAME WITH SCHEMABINDING AS BEGIN DECLARE @grp_name AS SYSNAME IF (SUSER_NAME() = 'Report_User') SET @grp_name = 'Group1' IF (APP_NAME() LIKE '%Management Studio%') SET @grp_name = 'Group2' RETURN @grp_name END GO ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION=dbo.fncClassifica_ResourceGovernor) ALTER RESOURCE GOVERNOR RECONFIGURE |
Reference: English - Portuguese
Workload Groups
View contentThe workload group of a session is defined through the Classifier function and it has some very important functions and limitations, such as defining the importance of requests that are part of the workload group.
Through parameter IMPORTANCE = {LOW | MEDIUM (Default) | HIGH}, you can set requests from this workload group to take precedence over connections from another workload group using the same resource pool (this parameter does not affect requests using another resource pool). This value is used to define the order of the request list of the same scheduler. If you have other schedulers available, 1 query with LOW importance and 1 query with HIGH importance, 2 queries can be executed concurrently.
The REQUEST_MAX_MEMORY_GRANT_PERCENT parameter specifies the maximum amount (in%) of memory that a connection can draw from the pool. Note that specifying this value for 0 will prevent queries using SORT and HASH JOIN from executing.
The REQUEST_MAX_CPU_TIME_SEC parameter allows you to define the maximum time, in seconds, that a query can execute (the default value is 0, ie no limit). If the request times out, a trace event will be generated. Until SQL Server version 2017 CU3, the session would not be interrupted when it reached this limit, but from this version this can be configured using the 2422 traceflag.
The MAX_DOP parameter allows defining the maximum amount of parallelism (Maximum Degree Of Parallelism - MAXDOP) of requests made in the workload group, where the default value is 0 and the allowed values are between 0 and 64. This setting overrides the parameter sp_configure 'max degree of parallelism 'and also the query hint OPTION (MAXDOP N).
The GROUP_MAX_REQUESTS parameter defines the maximum amount of concurrent requests executed by the workload group. The default value is 0, ie without limitation. When this number is reached, new connections will wait until the number of simultaneous requests is below the maximum.
Creation Example
1 2 3 4 5 6 7 8 9 10 |
CREATE WORKLOAD GROUP [Group1] WITH ( GROUP_MAX_REQUESTS=0, IMPORTANCE=LOW, REQUEST_MAX_CPU_TIME_SEC=2, REQUEST_MAX_MEMORY_GRANT_PERCENT=25, REQUEST_MEMORY_GRANT_TIMEOUT_SEC=0, MAX_DOP=0 ) USING [PoolA] GO |
Reference: English - Portuguese
Resource Pools or Resource Pools
View contentThe internal pool is used for SQL Server background processes and is a priority over any other pool. If it needs all the resources available on the instance, it will use it. In addition to the internal pool, there is also the default pool, which is used for the rest of the connections that have not been classified to use the internal pool nor the user's custom pools.
When you are creating a pool, you must specify the maximum and minimum CPU, Memory, and I / O (IOPS) limits.
The MIN_CPU_PERCENT parameter allows you to specify the minimum CPU value used by all pool requests, and is especially useful when CPU contention occurs as SQL Server will ensure that this value is available for use by connections in this pool. If the pool is not in use, this reserved CPU will be available for use by other pools until the pool in question has connections again.
The MAX_CPU_PERCENT parameter allows you to specify the maximum CPU% that pool requests can use on the instance. Note that the maximum CPU percentage is an opportunistic maximum. If CPU capacity is available, the workload will use it up to 100%. The maximum value will be applied only when there is contention for CPU resources.
The CAP_CPU_PERCENT parameter defines a “real” maximum limit on CPU usage by the pool. Workloads associated with the pool can use CPU capacity above the value of MAX_CPU_PERCENT when it is available, but not above the value of CAP_CPU_PERCENT.
The MIN_MEMORY_PERCENT parameter allows you to specify and reserve a minimum amount of memory that will always be pre-allocated in the instance to the pool, regardless of whether the pool is being used or not.
Remember that the sum of the minimum value for all pools cannot be greater than 100% and the value of the pool MAX_CPU_PERCENT parameter must be greater than the value of the MIN_CPU_PERCENT parameter.
The MIN_IOPS_PER_VOLUME and MAX_IOPS_PER_VOLUME parameters are used to determine the minimum and maximum IOPS amounts used by pool connections.
Creation Example
1 2 3 4 5 6 7 8 9 10 11 12 |
CREATE RESOURCE POOL [PoolA] WITH ( MIN_CPU_PERCENT=0, MAX_CPU_PERCENT=20, CAP_CPU_PERCENT=20, MIN_MEMORY_PERCENT=0, MAX_MEMORY_PERCENT=30, AFFINITY SCHEDULER = AUTO, MIN_IOPS_PER_VOLUME=0, MAX_IOPS_PER_VOLUME=300 ) GO |
Reference: English - Portuguese
How to check Resource Governor status and DMV's
View contentHere's the list of Resource Governor views:
- sys.resource_governor_configuration
- sys.resource_governor_external_resource_pool_affinity
- sys.resource_governor_external_resource_pools
- sys.resource_governor_resource_pool_affinity
- sys.resource_governor_resource_pools
- sys.resource_governor_workload_groups
Here is the list of Resource Governor DMV's
- sys.dm_resource_governor_configuration
- sys.dm_resource_governor_external_resource_pool_affinity
- sys.dm_resource_governor_external_resource_pools
- sys.dm_resource_governor_resource_pool_affinity
- sys.dm_resource_governor_resource_pool_volumes
- sys.dm_resource_governor_resource_pools
- sys.dm_resource_governor_workload_groups
How to enable Resource Governor
View content
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
USE [master] GO ---------------------------------------------------------------------------------------------- -- "Limpeza" do Resource Governor ---------------------------------------------------------------------------------------------- ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION=NULL) GO ALTER RESOURCE GOVERNOR RECONFIGURE GO ALTER RESOURCE GOVERNOR DISABLE GO IF (EXISTS(SELECT NULL FROM sys.resource_governor_workload_groups WHERE [name] = 'Grupo1')) DROP WORKLOAD GROUP [Grupo1] GO IF (EXISTS(SELECT NULL FROM sys.resource_governor_resource_pools WHERE [name] = 'PoolA')) DROP RESOURCE POOL [PoolA] GO IF (OBJECT_ID('dbo.fncClassifica_ResourceGovernor') IS NOT NULL) DROP FUNCTION dbo.fncClassifica_ResourceGovernor GO ---------------------------------------------------------------------------------------------- -- Criação do Pool de Recursos ---------------------------------------------------------------------------------------------- CREATE RESOURCE POOL [PoolA] WITH ( MIN_CPU_PERCENT=0, MAX_CPU_PERCENT=20, CAP_CPU_PERCENT=20, MIN_MEMORY_PERCENT=0, MAX_MEMORY_PERCENT=30, AFFINITY SCHEDULER = AUTO, MIN_IOPS_PER_VOLUME=0, MAX_IOPS_PER_VOLUME=300 ) GO ---------------------------------------------------------------------------------------------- -- Criação do Workload Group ---------------------------------------------------------------------------------------------- CREATE WORKLOAD GROUP [Grupo1] WITH ( GROUP_MAX_REQUESTS=0, IMPORTANCE=LOW, REQUEST_MAX_CPU_TIME_SEC=2, REQUEST_MAX_MEMORY_GRANT_PERCENT=25, REQUEST_MEMORY_GRANT_TIMEOUT_SEC=0, MAX_DOP=0 ) USING [PoolA] GO ---------------------------------------------------------------------------------------------- -- Criação da função de classificação ---------------------------------------------------------------------------------------------- CREATE FUNCTION fncClassifica_ResourceGovernor() RETURNS SYSNAME WITH SCHEMABINDING AS BEGIN DECLARE @grp_name AS SYSNAME, @Usuario VARCHAR(200) = SUSER_NAME(), @Programa VARCHAR(200) = APP_NAME() IF (@Usuario = 'Report_User') SET @grp_name = 'Grupo1' ELSE IF (@Programa LIKE '%Management Studio%') SET @grp_name = 'Grupo2' RETURN @grp_name END GO ---------------------------------------------------------------------------------------------- -- Habilita o Resource Governor, aplica a função de classificação e confirma as alterações ---------------------------------------------------------------------------------------------- ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION=dbo.fncClassifica_ResourceGovernor) GO ALTER RESOURCE GOVERNOR RECONFIGURE GO |
If you prefer, you can also use the Management Studio interface (GUI) to configure Resource Group and Workload group:
And with that, open the Resource Group and Workload group edit / create interface (it's the same interface for both):
Note that not all parameters are available in the SQL Server Management Studio interface (I tested on the 17.4 version), such as the I / O parameters. Therefore, I suggest that you use the command line to manage Resource Governor.
Testing the Resource Governor
View content- And performance of consultations? Will it change after implementing this feature?
- Does Resource Governor really work?
- Is it even possible to limit resources, such as disk, of certain sessions?
Let's do a simple test to prove it:
- Create a counter in Windows Perfmon (Performance Monitor) to monitor the Disk Read IO / sec counter of the MSSQL $ SQL2016: Resource Pool Stats object.
- Create a Resource Pool by limiting the maximum amount of IOPS (MAX_IOPS_PER_VOLUME) to 200.
- Run DBCC CHECKDB (dirceuresende) WITH NO_INFOMSGS Command
- Wait a few seconds and change the resource pool, increasing the maximum amount of IOPS by 2.000.
- Rerun DBCC CHECKDB (dirceuresende) WITH NO_INFOMSGS Command
- Collect Results and Compare Charts
After performing these steps, let's look at the result:
As seen in the chart, Resource Governor fulfilled its role and correctly limited the amount of disk IOPS used in 200 IOPS. After increasing the limit to 2.000 IOPS, we could see that the disk was able to reach up to 1.000 IOPS and could not only exceed this value due to hardware limitations, where it can also be observed that due to the higher limit of consumption of IOPS, the time to run checkdb was smaller.
How to disable Resource Governor
View content
1 2 3 4 5 6 7 8 |
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = NULL) GO ALTER RESOURCE GOVERNOR RECONFIGURE; GO ALTER RESOURCE GOVERNOR DISABLE; GO |
Remembering that current connections must be terminated (or restart the instance), otherwise Resource Governor will remain active and you will receive this error message:
Resource governor configuration failed. There are active sessions in workload groups being dropped or moved to different resource pools. Disconnect all active sessions in the affected workload groups and try again.
To also exclude Workloads groups and Resource Pools, you can also use the following commands:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = NULL) GO DECLARE @Query VARCHAR(MAX) = '' SELECT @Query += 'DROP WORKLOAD GROUP ' + QUOTENAME(name) + ';' FROM sys.resource_governor_workload_groups WHERE [name] not in ('internal','default'); EXEC(@Query) SET @Query = '' SELECT @Query += 'DROP RESOURCE POOL ' + QUOTENAME([name]) + ';' FROM sys.resource_governor_resource_pools WHERE [name] NOT IN ('internal','DEFAULT'); EXEC(@Query) ALTER RESOURCE GOVERNOR RECONFIGURE; GO ALTER RESOURCE GOVERNOR DISABLE; GO |
Monitoring Resource Governor Usage
View content
1 2 3 4 5 6 7 8 9 10 |
SELECT A.[name] AS resource_pool, COALESCE(SUM(B.total_request_count), 0) AS total_request_count, COALESCE(SUM(B.total_cpu_usage_ms), 0) AS total_cpu_usage_ms, (CASE WHEN SUM(B.total_request_count) > 0 THEN SUM(B.total_cpu_usage_ms) / SUM(B.total_request_count) ELSE 0 END) AS avg_cpu_usage_ms FROM sys.dm_resource_governor_resource_pools AS A LEFT OUTER JOIN sys.dm_resource_governor_workload_groups AS B ON A.pool_id = B.pool_id GROUP BY A.[name] |
Or monitor all CPU parameters of pools and workload groups:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
SELECT A.[name] AS resource_pool, B.[name] AS workload_group, A.total_cpu_usage_ms, A.min_cpu_percent, A.max_cpu_percent, A.cap_cpu_percent, A.total_cpu_delayed_ms, A.total_cpu_active_ms, A.total_cpu_violation_delay_ms, A.total_cpu_violation_sec, A.total_cpu_usage_preemptive_ms, B.total_cpu_limit_violation_count, B.total_cpu_usage_ms, B.max_request_cpu_time_ms, B.request_max_cpu_time_sec, B.total_cpu_usage_preemptive_ms FROM sys.dm_resource_governor_resource_pools AS A LEFT OUTER JOIN sys.dm_resource_governor_workload_groups AS B ON A.pool_id = B.pool_id |
You can also monitor resource pool I / O usage using the query below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
SELECT pool_id, [name], min_iops_per_volume, max_iops_per_volume, read_io_queued_total, read_io_issued_total, read_io_completed_total, read_io_throttled_total, read_bytes_total, read_io_stall_total_ms, read_io_stall_queued_ms, io_issue_violations_total, io_issue_delay_total_ms FROM sys.dm_resource_governor_resource_pools |
You can also use the query below to check which workload group is currently used by active sessions:
1 2 3 4 5 6 7 8 9 10 |
SELECT B.[name], A.* FROM sys.dm_exec_sessions AS A WITH (NOLOCK) LEFT JOIN sys.dm_resource_governor_workload_groups B ON A.group_id = B.group_id WHERE A.session_id > 50 AND A.session_id <> @@SPID AND (A.[status] != 'sleeping' OR (A.[status] = 'sleeping' AND A.open_transaction_count > 0)) |
If you want an even more complete version of this query, which can practically replicate sp_whoisactive's behavior, read the post. SQL Server - Query to return running queries (sp_WhoIsActive without consuming TempDB).
Best practices at Resource Governor
View content- Use the DAC: Because all new connections go through the Resource Governor classification function, a problem with this function can make it difficult to access the instance to correct the problem. To get around this easily, you can enable and use Dedicated Administrator Connection (DAC) on your instance, and thus be able to log in and change the sorting function. If you do not know how to do this, read the post Enabling and using dedicated remote administrator connection (DAC) in SQL Server.
- Beware of the classification function: As noted above, a coding error in the sort function can lead to very bad effects on your instance. To do this, avoid using functions or features that can make the response time of this function high. If the function needs to query a physical table, ensure that access is fast enough and the indexes are meeting the conditions of that query.
- Default Pool and Default Workload Group: A good practice when using Resource Governor is to leave some of the resources available to the default pool and default workload group. This is important because all non-SQL Server internal process sessions that cannot be classified into any custom pool will be part of the default pool. If this pool does not have the required resources available, these requests may have slow issues.
- Always monitor: After deploying Resource Governor, you should always be aware of and keep track of request flow and validate whether they are being directed to the right workload groups, and monitor potential new needs that require a change in the sorting function.
- Beware of memory settings: As already mentioned in this post, memory settings are pre-allocated when creating the pool, that is, even if the pool has no active connection and is not using this pre-allocated memory, it will still be reserved by the pool.
That's it folks!
A hug and see you next!
1 Response
[...] https://www.dirceuresende.com/blog/sql-server-utilizando-o-resource-governor-para-maior-controle-dos… [...]