1、背景
因历史遗留的问题,操作系统是Win Server2012,数据库版本SQLserver2012,示例下有好几个数据库。但是某个数据库在特定程序执行的时间点,就会打满这个服务器的CPU

2、方案使用 Resource Governor 限制数据库 CPU 使用率(推荐)
2.1、启用 Resource Governor
sql
-- 完整的配置脚本
USE master;
GO
-- 检查 Resource Governor 状态
SELECT
name,
state_desc,
max_cpu_percent,
min_cpu_percent
FROM sys.resource_governor_configuration;
-- 如果未启用,先启用
ALTER RESOURCE GOVERNOR RECONFIGURE;
GO
2.2、创建资源池(限制 CPU)
sql
-- 创建受限的资源池
CREATE RESOURCE POOL LimitedCPUPool
WITH (
MIN_CPU_PERCENT = 5, -- 最小 CPU 保证 5%
MAX_CPU_PERCENT = 20, -- 最大 CPU 使用 20%
CAP_CPU_PERCENT = 25 -- CPU 上限硬限制 25%
);
GO
-- 如果需要多个限制级别,可以创建多个资源池
CREATE RESOURCE POOL VeryLimitedCPUPool
WITH (
MIN_CPU_PERCENT = 2,
MAX_CPU_PERCENT = 10,
CAP_CPU_PERCENT = 15
);
GO
2.3、创建工作负载组
sql
-- 创建工作负载组关联到资源池
CREATE WORKLOAD GROUP LimitedCPUGroup USING LimitedCPUPool;
GO
CREATE WORKLOAD GROUP VeryLimitedCPUGroup USING VeryLimitedCPUPool;
GO
2.4、创建分类器函数
sql
USE master;
GO
-- 创建分类器函数,根据数据库名分配工作负载组
CREATE FUNCTION dbo.DatabaseCPUClassifier()
RETURNS SYSNAME
WITH SCHEMABINDING
AS
BEGIN
DECLARE @WorkloadGroup SYSNAME;
DECLARE @DatabaseName SYSNAME;
-- 获取当前数据库名
SET @DatabaseName = ORIGINAL_DB_NAME();
-- 根据数据库名分配不同的工作负载组
IF @DatabaseName IN ('YourTargetDatabase', 'TestDB')
SET @WorkloadGroup = 'LimitedCPUGroup';
ELSE IF @DatabaseName IN ('ArchiveDB', 'OldDB')
SET @WorkloadGroup = 'VeryLimitedCPUGroup';
ELSE
SET @WorkloadGroup = 'default';
RETURN @WorkloadGroup;
END;
GO
-- 应用分类器函数
ALTER RESOURCE GOVERNOR WITH (CLASSIFIER_FUNCTION = dbo.DatabaseCPUClassifier);
ALTER RESOURCE GOVERNOR RECONFIGURE;
GO
2.5、验证配置
sql
-- 查看资源池配置
SELECT
pool_id,
name,
min_cpu_percent,
max_cpu_percent,
cap_cpu_percent,
used_cpu_percentage
FROM sys.dm_resource_governor_resource_pools;
-- 查看工作负载组
SELECT
group_id,
name,
pool_id,
importance,
request_max_cpu_cost_percent
FROM sys.dm_resource_governor_workload_groups;
-- 查看分类器函数
SELECT name, definition FROM sys.objects
WHERE type = 'FN' AND name = 'DatabaseCPUClassifier';
-- 查看当前活动的会话和它们的工作负载组
SELECT
s.session_id,
s.login_name,
DB_NAME(s.database_id) AS DatabaseName,
wg.name AS WorkloadGroup,
rp.name AS ResourcePool,
s.cpu_time,
s.memory_usage
FROM sys.dm_exec_sessions s
LEFT JOIN sys.dm_resource_governor_workload_groups wg ON s.group_id = wg.group_id
LEFT JOIN sys.dm_resource_governor_resource_pools rp ON wg.pool_id = rp.pool_id
WHERE s.is_user_process = 1
ORDER BY s.cpu_time DESC;
2.6、效果图展示

3、注意事项
- Resource Governor 只影响新连接的会话,已存在的连接需要重新连接才能生效
- 测试环境先行:在生产环境部署前,务必在测试环境验证
- 监控影响:配置后持续监控性能和资源使用情况
- 逐步调整:CPU 限制百分比应该逐步调整,避免影响业务
- SQL Server 版本:Resource Governor 在 Standard 和 Enterprise 版本中功能有所不同