1. Resource Governor overview
A common (and unfortunate)
situation that DBAs often encounter in production systems is a single
runaway query that flatlines server performance to the detriment of all
users. Unless the offending query can be identified and killed, users
are effectively at the mercy of the query completing. To make matters
worse, there's nothing stopping the same query from occurring over and
over again, with the end result being an unpredictable experience for
end users and a frustrating one for DBAs.
In
previous versions of SQL Server, resources could be constrained at an
instance level with configuration settings such as CPU affinity and
maximum memory, but such settings are coarse grained and don't apply to
individual users or applications. Thus, instances that host groups of
users or applications with varying resource usage present a challenge
for a DBA whose goal is to provide a stable, predictable environment for
all users.
A classic example of this
is a SQL Server instance used for both reporting and data entry. In such
a case, performance for data entry users may be fine until someone
decides to run a large report, at which time data entry performance
grinds to a halt. Resource Governor is purpose built to address problems
of this type.
1.1. Resource Governor benefits
Put simply,
Resource Governor enables resource sharing and segregation between
groups of users or applications based on their connection source. For
example, we could assign our data entry group minimum CPU and memory
resources, effectively shielding them from the impact of a large report query.
As you'll see shortly,
Resource Governor is not only relatively easy to set up and use, but
it's also very effective in limiting the performance impact of one group
on others. That being said, there are a number of considerations before
using it, as well as several limitations.
1.2. Resource Governor limitations
As a brand-new
feature in SQL Server 2008, Resource Governor comes with a number of
limitations that will presumably be removed in subsequent SQL Server
versions as the feature matures:
Resource constraints are limited to memory and CPU. Network and disk I/O resources cannot be constrained in SQL Server 2008.
Reporting
Services, Analysis Services, and Integration Services resource usage
cannot be constrained. In this version, resource constraints apply to
core database engine usage only.
Resource Governor constraints are defined within (and apply within) a SQL Server instance; resource constraints do not apply across instances on a multi-instance server.
Further, Resource
Governor is most effective when resource usage is well defined and
consistent across a number of distinct groups, for example, data entry
and reports. In cases where particular data entry transactions dominate
resource usage, Resource Governor may not be effective, unless there is a
method of identifying and classifying the source of such transactions.
Before we dive into the details of Resource Governor, let's briefly define the major components.
1.3. Resource Governor components
Resource Governor tracks and allocates CPU and memory resources using three major components: resource pools, workload groups, and a classifier function:
A resource pool
is created to define the minimum and maximum usage of a server's CPU
and memory resources. A resource pool can be used by one or more
workload groups.
Connections
to a SQL Server instance are classified into a workload group by the
classifier function. The workload group is mapped to a resource pool
defining the minimum and maximum resource consumption available to the
connection. The resource group also serves as a monitoring and
aggregation point for resource consumption and as a method of applying a
uniform resource usage policy, for example, a MAXDOP setting specific
to each group.
The
classifier function, invoked upon connection to a SQL Server instance,
defines which resource group the connection is assigned to. Connections
can be classified based on the username, application name, host name, or
role membership.
Workload groups and
resource pools are either user defined or system based. There are two
system groups and pools: internal and default. The internal group and
pool are used for SQL Server processes, whereas the default group and
pool are used for connections that are not otherwise classified into a
user-defined group and pool.
Figure 1
illustrates the above components working together to define resource
usage limits for an incoming connection to a SQL Server 2008 instance.
With this overview in mind, let's consider the components in more detail, beginning with the classifier function.
2. Classifier function
When a user or application
connects to a SQL Server instance, the logon process includes two major
steps before the session is established: authentication, followed by the
firing of any logon triggers. When Resource Governor is enabled, a
third step is included for classifying the connection using the
classifier function. The process is summarized in figure 2.
Given the integration of the
classifier function within the logon process, the efficiency of the
function becomes a crucial consideration. Poorly written functions have
the potential for logins to time out if the execution time of the
function exceeds the login timeout setting of the connecting
application. Therefore, the classifier function should be tested,
ideally under load, before production implementation.
As with workload
groups and resource pools, the best classifier functions are those that
are relatively simple in nature. Consider the example in listing 1.
Example 1. Example classifier function
-- Create a Classifier Function
CREATE FUNCTION fn_rg_classifier() RETURNS SYSNAME
WITH SCHEMABINDING
AS
BEGIN
DECLARE @grp_name AS SYSNAME
IF (IS_SRVROLEMEMBER('sysadmin') = 1)
SET @grp_name = 'rgDBAGroup'
IF (APP_NAME() LIKE '%REPORT SERVER%')
SET @grp_name = 'rgReportGroup'
RETURN @grp_name
END
GO
|
The classifier function
presented here is an example of a relatively simple function putting
little overhead on the logon process. It uses the SUSR_NAME() and APP_NAME()
functions to classify incoming connections based on the username or
application name. The full list of supported functions for
classification purposes is as follows:
HOST_NAME()—Returns values such as MarketingPC4
APP_NAME()—Returns values such as Microsoft SQL Server Management Studio - Query
SUSER_NAME()andSUSER_SNAME()—Returns values such as BNESales\RColledge
IS_SRVROLEMEMBER()—Used to evaluate server role membership, for example, if IS_SRVROLEMEMBER ('sysadmin') = 1
IS_MEMBER()—Used to evaluate database role membership, for example, if IS_MEMBER ('db_owner') = 1
When designing a
classifier function, you need to consider the following aspects of its
effect on a Resource Governor implementation:
A connection
not explicitly classified will be assigned to the default workload group
(and therefore the default resource pool). With this in mind, the
function logic should address only connections that should be targeted
for a nondefault workload group.
Connections
made using the dedicated administrator connection (DAC) are not subject
to workload group classification. Using the DAC is one method of fixing
a poorly written classifier function that's denying connections based
on logon timeouts. For this reason, enabling the DAC is recommended when
using Resource Governor.
When
Resource Governor is disabled, the classifier function is not executed
as part of the logon process; all connections are automatically set to
use the default workload group, whose settings are returned to their
default values along with the values of the default resource pool.
Finally, you need to
consider the security of the functions being used (or misused) for
classification. One example of this, which also applies to logon
triggers , is spoofing the value of the supplied application name in an application's connection string. An example of this is shown in figure 3.
The Application Name attribute of the connection string is returned by the SQL Server APP_NAME()
function. It follows that a user with access to the application's
connection string and knowledge of the classification function's logic
can potentially circumvent the intended result of the classification
function (or logon trigger). Therefore, you must consider the security
of the connection string details and the possible use of a more secure
classification function.
Let's now focus on the purpose of the classifier function: to assign connections to a workload group.