适用于: SQL Server 2025 (17.x) 及更高版本
启用 tempdb 空间资源治理时,可以通过防止失控的查询或工作负载在 tempdb 中占用大量空间,从而提高可靠性并避免中断。
从 SQL Server 2025 (17.x)开始,可以使用资源调控器对工作负荷组消耗的总tempdb空间量强制实施限制。 当某个请求(查询)试图超出限制时,资源调控器会中止该请求,并返回一个明确的错误,表明工作负荷组限制已被强制实施。
实际上,可以在不同的工作负荷之间对共享 tempdb 空间进行分区。 例如,可以为任务关键型应用程序使用的工作负荷组设置更高的限制,并为所有其他工作负荷使用的工作负荷组设置下限 default 。
有关分步配置示例,请参阅 教程:配置 tempdb 空间资源治理的示例。
开始使用资源管理器
资源调控器提供了一个灵活的框架,可为不同的应用程序、用户、用户组等设置不同的 tempdb 空间限制。还可以根据自定义逻辑设置限制。
如果你不熟悉SQL Server中的资源调控器,请参阅资源调控器来了解其概念和功能。
有关资源调控器配置演练和最佳做法,请参阅 教程:资源调控器配置示例和最佳做法。
设置 tempdb 空间消耗限制
可以通过以下两种方式之一限制 tempdb 工作负荷组的空间消耗:
使用参数设置
GROUP_MAX_TEMPDB_DATA_MB。当您预先知道工作负载
tempdb的使用要求,或者tempdb的大小不会变化时,请使用固定限制。使用参数设置
GROUP_MAX_TEMPDB_DATA_PERCENT。如果您将来可能会更改
tempdb的最大大小,并且希望分配给每个工作负荷组的tempdb可用空间在不更改工作负荷组配置的情况下按比例变化,请使用百分比限制。 例如,如果您扩展运行 SQL Server 的 Azure VM 并增加最大tempdb大小,那么对于每个具有百分比限制的工作负载组,可用空间也会相应增加。
有关 GROUP_MAX_TEMPDB_DATA_MB 和 GROUP_MAX_TEMPDB_DATA_PERCENT 参数的更多信息,请参阅 CREATE WORKLOAD GROUP 或 ALTER WORKLOAD GROUP。
如果同时为同一工作负荷组指定固定限制和百分比限制,则固定限制优先于百分比限制。
在给定的 SQL Server 实例上,你可以混合使用 tempdb 空间消耗具有固定限制、百分比限制或不受限制的工作负荷组。 若要查看有效限制,请参阅 查看每个工作负荷组示例的有效 tempdb 空间限制 。
百分比限制配置
运行 ALTER RESOURCE GOVERNOR RECONFIGURE 该语句时,百分比限制将按下表生效:
| 配置 | DESCRIPTION | Tempdb 最大大小 (100%) | 百分比限制已生效 |
|---|---|---|---|
-
GROUP_MAX_TEMPDB_DATA_MB 未设置- 对于所有数据文件, MAXSIZE 不是 UNLIMITED- 对于所有数据文件, FILEGROWTH 不为零 |
tempdb 数据文件可以自动增长到其最大大小 |
所有数据文件的MAXSIZE值之和 |
是的 |
-
GROUP_MAX_TEMPDB_DATA_MB 未设置- 对于所有数据文件, MAXSIZE 为 UNLIMITED- 对于所有数据文件, FILEGROWTH 为零 |
tempdb 数据文件已预先发展到其预期大小,无法进一步增长 |
所有数据文件的SIZE值之和 |
是的 |
| 所有其他配置 | 否 |
tempdb若要查看配置,请参阅查看 tempdb 数据文件配置示例。
使用百分比限制时,请考虑以下事项:
如果设置
GROUP_MAX_TEMPDB_DATA_PERCENT并执行 ALTER RESOURCE GOVERNOR RECONFIGURE 语句,但数据文件配置不符合要求,则语句会成功完成并存储百分比限制,但不会强制执行这些限制。 在这种情况下,你会收到警告消息 10989,严重性为 10,该消息也记录在错误日志中:GROUP_MAX_TEMPDB_DATA_PERCENT is not in effect because tempdb configuration requirements aren't met.若要使百分比限制有效,请重新配置
tempdb数据文件以满足要求并再次执行ALTER RESOURCE GOVERNOR RECONFIGURE。 有关配置SIZE、FILEGROWTH和MAXSIZE的详细信息,请参阅ALTER DATABASE“文件和文件组选项”。如果百分比限制生效,并且您添加、删除或调整
tempdb数据文件的大小,则必须执行ALTER RESOURCE GOVERNOR RECONFIGURE来用新的最大大小tempdb(100%)更新资源调控器。
注释
对于新的SQL Server实例,数据文件MAXSIZEUNLIMITED大于FILEGROWTH零,这意味着百分比限制无效。 若要使用百分比限制,必须:
- 首先将数据文件
tempdb预先扩展到其预期大小,并将FILEGROWTH设置为零。 - 将每个数据文件的
MAXSIZE设置为有限值。 - 对于每个
tempdb数据文件卷,请确保卷上文件的值总和MAXSIZE小于或等于卷上的可用磁盘空间。 例如,如果卷的可用空间为 100 GB,并且有两个tempdb数据文件,则每个MAXSIZE文件为 50 GB 或更少。
工作原理
本部分 tempdb 详细介绍了空间资源治理。
在
tempdb中分配和解除分配数据页时,资源调控器会记录每个工作负荷组所消耗的tempdb空间。如果启用了资源调控器,并且
tempdb为工作负荷组设置了空间消耗限制,并且工作负荷组中运行的请求(查询)会尝试使组的总tempdb空间消耗超出限制,则请求中止并出现错误 1138,严重性为 17:Could not allocate a new page for database 'tempdb' because that would exceed the limit set for workload group 'workload-group-name'".当请求中止并出现错误 1138 时,
total_tempdb_data_limit_violation_count动态管理视图(DMV)列中的值将递增一个,并tempdb_data_workload_group_limit_reached触发扩展事件。资源调节器会跟踪所有可归因于工作负载组的
tempdb使用情况,包括临时表、变量(包括表变量)、表值参数、非临时表、游标,以及查询处理过程中的tempdb使用情况,例如缓冲区、溢出、工作表和工作文件。tempdb中全局临时表和非临时表的空间消耗,将计入向该表插入第一行的负载组名下,即使其他负载组中的会话对同一张表添加、修改或删除了行。每个工作负载组的配置的
tempdb消耗限制在 sys.resource_governor_workload_groups 目录视图以及group_max_tempdb_data_mb和group_max_tempdb_data_percent列中公开。工作负荷组的
tempdb空间的当前消耗量和峰值消耗量分别在 sys.dm_resource_governor_workload_groups DMV 以及tempdb_data_space_kb和peak_tempdb_data_space_kb列中公开。tempdb版本存储的使用(包括在启用了加速数据库恢复(ADR) 时的持久版本存储(PVS))不受限制,因为多个工作负荷组中的请求可能会使用行版本。tempdb中的空间消耗按使用的 8 KB 数据页数计算。 即使页面中的数据未完全填满,它也会使工作负载组的tempdb消耗增加 8 KB。tempdb空间计账在负载组的生命周期内持续维护。 如果在全局临时表或与该工作负荷组关联的数据的非临时表仍存在于tempdb时删除了工作负荷组,那么这些表所使用的空间不会被计入其他任何工作负荷组。tempdb空间资源治理控制tempdb数据文件中的空间,但不控制基础卷上的磁盘空间。 除非预先将tempdb数据文件扩展到其预期大小,否则tempdb所在卷上的空间可能会被其他文件占用。 如果tempdb没有剩余空间供数据文件增长,则在tempdb达到任何工作负荷组的空间消耗限制之前,tempdb可能会耗尽空间。空间资源治理
tempdb适用于数据文件,但不适用于事务日志文件。 为了确保tempdb中的事务日志不会占用大量空间,请在中启用tempdb。
与会话级空间跟踪的区别
sys.dm_db_session_space_usage DMV 为每个会话提供 tempdb 空间分配和释放统计信息。 即使工作负荷组中只有一个会话,此 DMV 中的空间使用情况统计信息可能与 sys.dm_resource_governor_workload_groups 视图中的统计信息完全不匹配,原因如下:
- 与
sys.dm_resource_governor_workload_groups不同,sys.dm_db_session_space_usage:- 不反映
tempdb当前正在运行的任务的空间使用情况。sys.dm_db_session_space_usage中的统计信息在任务完成时更新。sys.dm_resource_governor_workload_groups统计信息会持续更新。 - 不跟踪索引分配映射 (IAM) 页。 有关详细信息,请参阅 页面和范围体系结构指南。
- 不反映
- 在行被删除后,或者当表、索引或分区被删除或截断时,数据库引擎会释放数据页。 该释放操作可能是同步的,也可能由异步后台进程执行。
sys.dm_resource_governor_workload_groups即使导致这些页面解除分配的会话已经关闭且不再存在于sys.dm_db_session_space_usage中,它仍然反映这些页面解除分配的情况。
tempdb 空间资源治理的最佳做法
在配置 tempdb 空间资源治理之前,请考虑以下最佳做法:
请查阅资源管理器的通用最佳实践。
对于大多数方案,请避免将
tempdb空间消耗限制设置为小值或零,尤其是对于default工作负荷组。 如果将此限制设置为小值或零,则许多常见任务在需要分配空间时tempdb可能会开始失败。 例如,如果将工作负荷组的固定或百分比限制设置为 0default,则可能无法在 SQL Server Management Studio(SSMS)中打开对象资源管理器。除非您创建了自定义工作负载组以及将工作负载分配到专用组的分类器函数,否则请避免限制
default工作负载组的tempdb使用。 如果限制default工作负载组的tempdb空间消耗,查询可能会返回错误 1138。 当tempdb仍有未使用且无法被任何用户工作负载占用的空间时,就会发生此错误。所有工作负荷组的值之和
GROUP_MAX_TEMPDB_DATA_MB可以超过最大tempdb大小。 例如,如果最大大小为 100 GB,那么工作负荷组tempdb和工作负荷组GROUP_MAX_TEMPDB_DATA_MB的限制可以是 80 GB 每组。此方法仍会通过为其他工作负荷组保留 20 GB 空间,阻止每个工作负荷组占用
tempdb中的所有空间。 同时,当可用tempdb空间仍然可用时,可以避免不必要的查询中止,因为工作负荷组 A 和 B 不太可能同时占用大量tempdb空间。同样,所有工作负荷组的值总和
GROUP_MAX_TEMPDB_DATA_PERCENT可以超过 100%。 如果知道多个组不太可能同时导致高tempdb使用率,则可以为每个组分配更多tempdb空间。
例子
查看 tempdb 数据文件配置
以下查询显示当前 tempdb 数据文件配置:
SELECT file_id,
name,
size * 8. / 1024 AS size_mb,
IIF (max_size = -1, NULL, max_size * 8. / 1024) AS maxsize_mb,
IIF (is_percent_growth = 0, growth * 8. / 1024, NULL) AS filegrowth_mb,
IIF (is_percent_growth = 1, growth, NULL) AS filegrowth_percent
FROM sys.master_files
WHERE database_id = 2
AND type_desc = 'ROWS';
对于结果集中的给定文件:
- 如果列
maxsize_mb为NULL,则MAXSIZE为UNLIMITED。 - 如果任一或
filegrowth_mbfilegrowth_percent为零,则FILEGROWTH为零。
查看每个工作负荷组的有效 tempdb 空间限制
以下查询显示了每个工作负荷组的有效 tempdb 空间消耗限制。 对于 固定限制 或 百分比限制 配置,返回的限制值均以兆字节为单位。
group_effective_limit_mb如果该列是NULL,则表示以下项之一:
- 未配置固定限制和百分比限制。
- 不符合使用百分比限制配置 的要求 。
SELECT wg.group_id,
wg.name,
tf.tempdb_max_size_mb,
CASE
WHEN wg.group_max_tempdb_data_mb IS NOT NULL
THEN wg.group_max_tempdb_data_mb
WHEN wg.group_max_tempdb_data_percent IS NOT NULL AND tf.tempdb_max_size_mb IS NOT NULL
THEN 0.01 * wg.group_max_tempdb_data_percent * tf.tempdb_max_size_mb
ELSE NULL END AS group_effective_limit_mb
FROM sys.resource_governor_workload_groups AS wg
CROSS APPLY (
SELECT IIF (SUM(IIF (max_size <> -1
AND growth > 0, 1, 0)) = COUNT(1) /* autogrow up to the maxsize */
OR SUM(IIF (max_size = -1
AND growth = 0, 1, 0)) = COUNT(1), /* pregrown and fixed */
SUM(IIF (growth = 0, size, max_size)) * 8 / 1024., NULL) AS tempdb_max_size_mb
FROM sys.master_files
WHERE database_id = 2
AND type_desc = 'ROWS'
) AS tf;