Tempdb 空间资源治理

适用于: 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_MBGROUP_MAX_TEMPDB_DATA_PERCENT 参数的更多信息,请参阅 CREATE WORKLOAD GROUPALTER 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 未设置
- 对于所有数据文件, MAXSIZEUNLIMITED
- 对于所有数据文件, 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 。 有关配置SIZEFILEGROWTHMAXSIZE的详细信息,请参阅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_mbgroup_max_tempdb_data_percent 列中公开。

    工作负荷组的 tempdb 空间的当前消耗量和峰值消耗量分别在 sys.dm_resource_governor_workload_groups DMV 以及 tempdb_data_space_kbpeak_tempdb_data_space_kb 列中公开。

    小窍门

    即使未设置 tempdb_data_space_kb 空间消耗限制,也会保留 peak_tempdb_data_space_kb 中的 tempdb 列。

    可以创建分类器函数和工作负荷组,而无需最初设置任何限制。 监视 tempdb 每个组随时间推移的使用情况,以建立具有代表性的使用模式,然后根据需要设置限制。

  • 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可能会开始失败。 例如,如果将工作负荷组的固定或百分比限制设置为 0 default ,则可能无法在 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 空间仍然可用时,可以避免不必要的查询中止,因为工作负荷组 AB 不太可能同时占用大量 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_mbNULL,则 MAXSIZEUNLIMITED
  • 如果任一或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;

后续步骤