适用于:SQL Server
Azure SQL 数据库
Azure SQL 托管实例
Microsoft Fabric SQL 数据库
本文介绍 tempdb
系统数据库、可供连接到 SQL Server、Azure SQL 数据库或 Azure SQL 托管实例中的数据库引擎实例的所有用户可用的全局资源。
概述
tempdb
系统数据库是包含以下内容的全局资源:
显式创建的用户对象。 其中包括:
- 全局或本地临时表以及这些表上的索引
- 临时存储过程
- 大型变量,包括表变量
- 表值函数中返回的表
- 游标
也可以在用户数据库中创建
tempdb
的用户对象,但是创建对象时没有持续性保证,并在数据库引擎实例重启时删除。数据库引擎创建的内部对象。 其中包括:
- 用于储存假脱机、游标、排序和临时大型对象 (LOB) 存储的中间结果的工作表。
- 用于哈希匹配或哈希聚合操作的工作文件。
- 用于创建或重新生成索引等操作(如果指定了
SORT_IN_TEMPDB
)的中间排序结果,或者某些GROUP BY
、ORDER BY
或UNION
查询的中间排序结果。
每个内部对象至少使用九页:一个 IAM 页,一个八页的盘区。 有关页和盘区的详细信息,请参阅页和盘区。
版本存储,它们是包含支持 行版本控制的数据行的数据页的集合。 版本存储区包含:
- 使用基于
READ COMMITTED
行版本控制或SNAPSHOT
隔离事务的数据库中的数据修改事务生成的行版本。 - 由数据修改事务为实现联机索引操作、多重活动结果集 (MARS) 以及
AFTER
触发器等功能而生成的行版本。
从 SQL Server 2025(17.x) 预览版开始,启用加速数据库恢复(ADR)
tempdb
时,tempdb
包含两个不同的独立版本存储:- 传统版本存储,用于未启用 ADR 的用户数据库中事务生成的行版本。
- 持久版本存储(PVS),用于在
tempdb
中事务生成的行版本。
如果在
tempdb
启用了 ADR,请确保为tempdb
数据文件分配足够的磁盘空间以容纳两个版本存储。 取决于您的工作负荷,tempdb
数据文件的大小可能需要增加才能包含 PVS 数据。有关传统版本存储的空间使用情况的详细信息
tempdb
,请参阅 tempdb 中使用的空间。 有关 PVS 使用的空间的详细信息,请参阅 持久版本存储(PVS)使用的空间。- 使用基于
tempdb
中的操作记录最少。
tempdb
每次启动数据库引擎时都会重新创建,以便系统始终以空 tempdb
数据库开头。 创建临时存储过程的会话断开时,会自动删除临时存储过程和本地临时表。
tempdb
在数据库引擎的各个正常运行时间段之间,始终没有内容需要保存。 不允许对 tempdb
执行备份和还原操作。
SQL Server 中 tempdb 的物理属性
下表列出了 SQL Server 中 tempdb
数据和日志文件的初始配置值。 这些值基于 model
数据库的默认值。 对于不同版本的 SQL Server,这些文件的大小可能略有不同。
文件 | 逻辑名称 | 物理名称 | 初始大小 | 文件增长 |
---|---|---|---|---|
主数据 | tempdev |
tempdb.mdf |
8 MB | 以 64 MB 的速度自动增长直到磁盘已满 |
次要数据文件 | temp# |
tempdb_mssql_#.ndf |
8 MB | 以 64 MB 的速度自动增长直到磁盘已满 |
日志 | templog |
templog.ldf |
8 MB | 以 64 MB 的速度自动增长直到达到上限 2 TB |
所有 tempdb
数据文件应始终具有相同的初始大小和增长参数。
tempdb 数据文件数
根据数据库引擎的版本及其配置和工作负荷, tempdb
可能需要多个数据文件来缓解分配争用。
建议的数据文件总数取决于计算机上的逻辑处理器数。 作为一般指南:
- 如果逻辑处理器数小于或等于 8,请使用相同数量的数据文件。
- 如果逻辑处理器数大于 8,请指定 8 个数据文件。
- 如果仍然观察到
tempdb
分配争用,请将数据文件的数量增加为四的倍数,直到争用减少到可接受的级别,或者对工作负载进行更改。
有关详细信息,请参阅 有关减少 SQL Server tempdb 数据库中分配争用的建议。
若要检查tempdb
中当前的大小和增长参数,请使用tempdb
中的sys.database_files目录视图。
在 SQL Server 中移动 tempdb 数据和日志文件
若要移动 tempdb
数据和日志文件,请参阅移动系统数据库。
SQL Server 中 tempdb 的数据库选项
下表列出了 tempdb
数据库中每个数据库选项的默认值以及该选项是否可以修改。 若要查看这些选项的当前设置,请使用 sys.databases 目录视图。
数据库选项 | 默认值 | 是否可修改 |
---|---|---|
ACCELERATED_DATABASE_RECOVERY |
OFF |
是1 |
ALLOW_SNAPSHOT_ISOLATION |
OFF |
是 |
ANSI_NULL_DEFAULT |
OFF |
是 |
ANSI_NULLS |
OFF |
是 |
ANSI_PADDING |
OFF |
是 |
ANSI_WARNINGS |
OFF |
是 |
ARITHABORT |
OFF |
是 |
AUTO_CLOSE |
OFF |
否 |
AUTO_CREATE_STATISTICS |
ON |
是 |
AUTO_SHRINK |
OFF |
否 |
AUTO_UPDATE_STATISTICS |
ON |
是 |
AUTO_UPDATE_STATISTICS_ASYNC |
OFF |
是 |
AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN) |
OFF |
否 |
CHANGE_TRACKING |
OFF |
否 |
COMPATIBILITY_LEVEL |
取决于数据库引擎版本。 有关详细信息,请参阅 ALTER DATABASE (Transact-SQL) 兼容性级别。 |
是 |
CONCAT_NULL_YIELDS_NULL |
OFF |
是 |
CONTAINMENT |
NONE |
否 |
CURSOR_CLOSE_ON_COMMIT |
OFF |
是 |
CURSOR_DEFAULT |
GLOBAL |
是 |
数据库状态 | ONLINE |
否 |
数据库更新 | READ_WRITE |
否 |
数据库用户访问 | MULTI_USER |
否 |
DATE_CORRELATION_OPTIMIZATION |
OFF |
是 |
DB_CHAINING |
ON |
否 |
DELAYED_DURABILITY |
DISABLED 无论选项如何, tempdb 的延迟持久性始终启用。 |
是 |
ENCRYPTION |
OFF |
否 |
MIXED_PAGE_ALLOCATION |
OFF |
否 |
NUMERIC_ROUNDABORT |
OFF |
是 |
PAGE_VERIFY |
CHECKSUM 用于 SQL Server 的新安装在就地升级 SQL Server 实例时,可能会保留现有 PAGE_VERIFY 值。 |
是 |
PARAMETERIZATION |
SIMPLE |
是 |
QUOTED_IDENTIFIER |
OFF |
是 |
READ_COMMITTED_SNAPSHOT |
OFF |
否 |
RECOVERY |
SIMPLE |
否 |
RECURSIVE_TRIGGERS |
OFF |
是 |
服务代理商 | ENABLE_BROKER |
是 |
TARGET_RECOVERY_TIME |
六十 | 是 |
TEMPORAL_HISTORY_RETENTION |
ON |
是 |
TRUSTWORTHY |
OFF |
否 |
1 在 tempdb
中设置为 ON
从 SQL Server 2025(17.x)预览版开始得到支持。 在以前版本的 SQL Server 中,不允许修改 ACCELERATED_DATABASE_RECOVERY
数据库的选项 tempdb
。
有关这些数据库选项的说明,请参阅 ALTER DATABASE SET 选项 (Transact-SQL)。
Azure SQL 数据库 中的 tempdb
在 Azure SQL 数据库中,行为和配置的一些方面 tempdb
不同于 SQL Server。
对于单一数据库,逻辑服务器上的每个数据库都有自己的 tempdb
。 在弹性池中,是同一池中所有数据库的共享资源, tempdb
但由一个数据库创建的临时对象对同一弹性池中的其他数据库不可见。
tempdb
中的对象,包括目录视图和动态管理视图(DMV),可以通过到tempdb
数据库的跨数据库引用访问。 例如,可以查询 sys.database_files 视图:
SELECT file_id,
type_desc,
name,
size,
max_size,
growth
FROM tempdb.sys.database_files;
Azure SQL 数据库中的全局临时表受数据库范围限制。 有关详细信息,请参阅 Azure SQL 数据库中的数据库范围的全局临时表。
若要详细了解 Azure SQL 数据库中的 tempdb
大小,请查看:
SQL 托管实例中的 tempdb
在 Azure SQL 托管实例中 tempdb
,行为和默认配置的某些方面不同于 SQL Server。
可以配置 tempdb
文件数、其增长增量及其最大大小。 有关在 Azure SQL 托管实例中配置 tempdb
设置的详细信息,请参阅为 Azure SQL 托管实例配置 tempdb 设置。
Azure SQL 托管实例支持临时对象的方式与 SQL Server 相同,其中所有全局临时表和全局临时存储过程都可供同一 SQL 托管实例中的所有用户会话访问。
若要详细了解 Azure SQL 托管实例中的 tempdb
大小,请查看资源限制。
Fabric 中 SQL 数据库中的 tempdb
若要详细了解 tempdb
Microsoft Fabric 中的 SQL 数据库中的大小,请查看功能比较中的资源限制部分 :Microsoft Fabric 中的 Azure SQL 数据库和 SQL 数据库。
与 Azure SQL 数据库类似, Microsoft Fabric 中的 SQL 数据库中 的全局临时表具有数据库范围。 有关详细信息,请参阅 Azure SQL 数据库中的数据库范围的全局临时表。
限制
不能在 tempdb
数据库中执行下列操作:
- 添加文件组。
- 备份或还原数据库。
- 更改排序规则。 默认排序规则为服务器排序规则。
- 更改数据库所有者。
tempdb
的所有者是 sa。 - 创建数据库快照。
- 删除数据库。
- 从数据库中删除 guest 用户。
- 启用变更数据捕获。
- 参与数据库镜像。
- 删除主文件组、主数据文件或日志文件。
- 重命名数据库或主文件组。
- 正在运行
DBCC CHECKALLOC
。 - 正在运行
DBCC CHECKCATALOG
。 - 将数据库设置为
OFFLINE
。 - 将数据库或主文件组设置为
READ_ONLY
。
权限
任何用户都可以在 tempdb
中创建临时对象。
用户只能访问自己的非临时对象 tempdb
,除非他们收到其他权限。
可以撤销数据库用户或角色对tempdb
的tempdb
权限,以阻止其使用。 不建议这样做,因为许多操作都需要使用 tempdb
。
在 SQL Server 中优化 tempdb 性能
文件的大小和物理位置 tempdb
可能会影响性能。 例如,如果初始大小 tempdb
太小,则每次重启数据库引擎实例时,可能需要花费时间和资源自动增长 tempdb
以支持工作负荷所需的大小。
- 如果可能,请使用 即时文件初始化 来提高数据文件增长作的性能。
- 从 SQL Server 2022(16.x)开始,最多到 64 MB 的事务日志文件增长事件也能受益于即时文件初始化。 有关详细信息,请参阅 即时文件初始化和事务日志。
- 通过将文件大小设置为足够容纳环境中典型工作负载的值来预分配所有
tempdb
文件的空间。 预分配会阻止tempdb
自动增长的频率过高,这可能会对性能产生负面影响。 - 数据库中的文件
tempdb
应设置为自动增长,以在计划外增长事件期间提供空间。 - 划分
tempdb
为大小相等的多个数据文件可以提高使用tempdb
的作效率。- 为了避免数据分配不平衡,数据文件应具有相同的初始大小和增长参数,因为数据库引擎使用比例填充算法,该算法有利于在具有更多可用空间的文件中分配。
- 将文件增长增量设置为合理的大小,例如 64 MB,并使所有数据文件的增长增量相同,以防止增长不平衡。
- 从 SQL Server 2025(17.x)预览版开始,请考虑在
tempdb
启用加速数据库恢复,以便在tempdb
获得即时事务回滚和积极日志截断的好处。 有关详细信息,请参阅 tempdb 中的 ADR。- 启用或禁用ADR
tempdb
需要重启数据库引擎才能生效。
- 启用或禁用ADR
要检查 tempdb
的当前大小和增长参数,请使用以下查询:
SELECT name AS file_name,
type_desc AS file_type,
size * 8.0 / 1024 AS size_mb,
max_size * 8.0 / 1024 AS max_size_mb,
CAST(IIF(max_size = 0, 0, 1) AS bit) AS is_autogrowth_enabled,
CASE WHEN growth = 0 THEN growth
WHEN growth > 0 AND is_percent_growth = 0 THEN growth * 8.0 / 1024
WHEN growth > 0 AND is_percent_growth = 1 THEN growth
END
AS growth_increment_value,
CASE WHEN growth = 0 THEN 'Autogrowth is disabled.'
WHEN growth > 0 AND is_percent_growth = 0 THEN 'Megabytes'
WHEN growth > 0 AND is_percent_growth = 1 THEN 'Percent'
END
AS growth_increment_value_unit
FROM tempdb.sys.database_files;
将 tempdb
数据库放置在快速 I/O 子系统中。 除非遇到磁盘级 I/O 瓶颈,否则单个数据文件或数据文件组 tempdb
不一定需要位于不同的磁盘上。
如果 tempdb
与用户数据库之间存在 I/O 争用,请将 tempdb
文件放在与用户数据库不同的磁盘上。
注意
为了提高性能,即使数据库选项DELAYED_DURABILITY
设置为DISABLED
,在tempdb
上始终会启用延迟持续性。 由于 tempdb
在启动时重新创建,因此它不会经历恢复过程,也不会提供持久性保证。
针对 SQL Server 的 tempdb 改进事项
SQL Server 2025(17.x) 预览版中引入
-
Tempdb
空间资源治理对应用程序或用户工作负荷消耗的空间tempdb
总量强制实施限制。 这提高了可靠性并避免中断,其方法是防止失控的查询或工作负载占用tempdb
的大量空间。 有关详细信息,请参阅 Tempdb 空间资源治理。 - 支持
tempdb
中的加速数据库恢复,为tempdb
的事务提供即时的事务回滚和主动的日志截断。 -
优化万圣节保护 通过不使用万圣节保护缓冲机制来处理
tempdb
中的数据修改语言(DML)语句,从而减少空间使用量。
在 SQL Server 2022 (16.x) 中引入
- 通过 系统页闩锁并发增强功能引入了改进的可伸缩性。 对全局分配映射 (GAM) 页和共享全局分配映射 (SGAM) 页的并发更新可减少分配/解除分配数据页和区时的页闩锁争用。 这些增强功能适用于所有用户数据库,并且在
tempdb
的重负荷使用情况下尤其有利。 有关 GAM 和 SGAM 页面的详细信息,请阅读表象之下:GAM、SGAM 和 PFS 页面。 有关详细信息,请观看系统页闩锁并发增强功能 (Ep. 6) |公开的数据。
在 SQL Server 2019 (15.x) 中引入
- 打开
tempdb
文件以允许最大磁盘吞吐量时,数据库引擎不使用FILE_FLAG_WRITE_THROUGH
此选项。 由于tempdb
在启动时重新创建,因此不需要此选项来提供数据持续性。 有关FILE_FLAG_WRITE_THROUGH
的详细信息,请参阅在 SQL Server 中扩展数据可靠性的日志记录和数据存储算法。 -
内存优化 TempDB 元数据消除了临时对象元数据争用。
tempdb
- 并发页可用空间 (PFS) 页更新可减少所有数据库中的页面闩锁争用,这是最常见的
tempdb
问题。 此改进更改了 PFS 页面更新的并发管理机制,使得它们可以在共享锁机制下进行更新,而不是在独占锁机制下进行。 自 SQL Server 2019 (15.x) 起,此行为在所有数据库(包括tempdb
)中默认处于启用状态。 有关 PFS 页面的详细信息,请阅读表象之下:GAM、SGAM 和 PFS 页面。 - 默认情况下,Linux 上的 SQL Server 新安装会根据逻辑内核数创建多个
tempdb
数据文件(最多八个数据文件)。 这不适用于就地次要版本或主版本升级。 每个tempdb
数据文件为 8 MB,文件自动增长为 64 MB。 此行为类似于 Windows 上的默认 SQL Server 安装。
在 SQL Server 2017 (14.x) 中引入
- SQL 安装体验改进了初始
tempdb
文件分配指南。 如果初始文件大小设置为大于 1 GB 的值且未启用即时文件初始化,则 SQL 安装程序会警告客户,防止实例启动延迟。 -
sys.dm_tran_version_store_space_usage动态管理视图跟踪每个数据库的版本存储使用情况。 此 DMV 对于希望根据每个数据库的版本存储使用要求主动计划
tempdb
大小调整的 DBA 非常有用。 -
智能查询处理 功能(如自适应联接和内存授予反馈)可减少连续执行的内存溢出,从而减少
tempdb
利用率。
在 SQL Server 2016 (13.x) 中引入
- 已缓存的临时表和表变量。 缓存允许删除和创建临时对象的操作非常快速地运行。 缓存还可以减少页分配和元数据争用问题。
- 改进了分配页闩锁协议,减少了所用
UP
(更新)闩锁的数量。 - 减少了
tempdb
的日志记录开销,从而减少了tempdb
日志文件的磁盘 I/O 带宽消耗。 - SQL 安装程序在新实例安装期间添加多个
tempdb
数据文件。 查看建议,并在 SQL 安装程序中的数据库引擎配置页配置您的tempdb
,或使用命令行参数/SQLTEMPDBFILECOUNT
。 默认情况下,SQL 安装程序会添加与逻辑处理器数量相同的tempdb
数据文件或 8 个,以数量较少者为准。 - 如果有多个
tempdb
数据文件,那么所有文件都会同时自动增长相同的量,具体取决于增长设置。 不再需要跟踪标志 1117。 有关详细信息,请阅读 TEMPDB 和用户数据库的 -T1117 和 -T1118 更改。 -
tempdb
中的所有分配使用统一盘区。 不再需要跟踪标志 1118。 有关tempdb
中性能改进的详细信息,请参阅博客文章 TEMPDB - Files and Trace Flags and Updates, Oh My!(TEMPDB - 文件和跟踪标志以及更新,天哪!)。 - 始终为
PRIMARY
文件组启用AUTOGROW_ALL_FILES
属性。
内存优化 TempDB 元数据
临时对象元数据争用一直是许多 SQL Server 工作负荷可伸缩性的瓶颈。 为了解决此问题,SQL Server 2019 (15.x) 引入了内存 中数据库 功能系列的一部分功能:内存优化 TempDB 元数据。
启用内存优化的 TempDB 元数据功能可以消除以前由于临时对象元数据争用而受到限制的工作负荷瓶颈 tempdb
。 从 SQL Server 2019(15.x)开始,管理临时对象元数据所涉及的系统表可能会变成无闩锁、非持久、内存优化表。
小窍门
由于当前 限制,建议仅在发生对象元数据争用并显著影响工作负荷时启用内存优化 TempDB 元数据。
如果发生临时对象元数据争用,以下诊断查询将返回一行或多行。 每行表示一个 系统表,并返回在执行此诊断查询时争用该表访问的会话数。
SELECT OBJECT_NAME(dpi.object_id, dpi.database_id) AS system_table_name,
COUNT(DISTINCT(r.session_id)) AS session_count
FROM sys.dm_exec_requests AS r
CROSS APPLY sys.fn_PageResCracker(r.page_resource) AS prc
CROSS APPLY sys.dm_db_page_info(prc.db_id, prc.file_id, prc.page_id, 'LIMITED') AS dpi
WHERE dpi.database_id = 2
AND dpi.object_id IN (3, 9, 34, 40, 41, 54, 55, 60, 74, 75)
AND UPPER(r.wait_type) LIKE N'PAGELATCH[_]%'
GROUP BY dpi.object_id, dpi.database_id;
观看此七分钟的视频,大致了解如何使用内存优化 TempDB 元数据功能以及何时使用:
注意
目前,内存优化 TempDB 元数据功能在 Azure SQL 数据库、Microsoft Fabric 中的 SQL 数据库和 Azure SQL 托管实例中不可用。
配置和使用内存优化的 TempDB 元数据
以下部分包括启用、配置、验证和禁用内存优化 TempDB 元数据功能的步骤。
启用
若要启用此功能,请使用以下脚本:
ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON;
有关详细信息,请参阅 ALTER SERVER。 此配置更改需要重新启动服务才能生效。
可使用以下 T-SQL 命令验证 tempdb
是否经过内存优化:
SELECT SERVERPROPERTY('IsTempdbMetadataMemoryOptimized');
如果返回的值为 1,并在启用该功能后重启,则启用该功能。
如果在启用内存优化 TempDB 元数据后服务器由于任何原因而无法启动,则可以使用-f
启动选项以最少的配置启动数据库引擎实例来绕过该功能。 然后,可以 禁用 该功能,并删除 -f
在正常模式下重启数据库引擎的选项。
绑定到资源池以限制内存使用量
为了保护服务器免受潜在的内存不足情况影响,我们建议您将 tempdb
绑定到资源调控器下的 资源池,以限制内存优化型 TempDB 元数据消耗的内存。 以下示例脚本创建一个资源池,并将其最大内存设置为 20%,启用 资源调控器并绑定到 tempdb
资源池。
此示例使用 20% 作为演示目的的内存限制。 环境中的最佳值可能更大或更小,具体取决于工作负荷,如果工作负荷发生更改,可能会随时间变化。
CREATE RESOURCE POOL tempdb_resource_pool
WITH (MAX_MEMORY_PERCENT = 20);
ALTER RESOURCE GOVERNOR RECONFIGURE;
ALTER SERVER CONFIGURATION
SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON
(RESOURCE_POOL = 'tempdb_resource_pool');
此更改还需要重启服务才能生效,即使已启用内存优化 TempDB 元数据也是如此。
验证资源池绑定并监视内存使用情况
若要验证是否已 tempdb
绑定到资源池并监视池的内存使用情况统计信息,请使用以下查询:
WITH resource_pool AS
(
SELECT p.pool_id,
p.name,
p.max_memory_percent,
dp.max_memory_kb,
dp.target_memory_kb,
dp.used_memory_kb,
dp.out_of_memory_count
FROM sys.resource_governor_resource_pools AS p
INNER JOIN sys.dm_resource_governor_resource_pools AS dp
ON p.pool_id = dp.pool_id
)
SELECT SERVERPROPERTY('IsTempdbMetadataMemoryOptimized') AS is_tempdb_memory_optimized_metadata_enabled,
rp.name AS resource_pool_name,
rp.max_memory_percent,
rp.max_memory_kb,
rp.target_memory_kb,
rp.used_memory_kb,
rp.out_of_memory_count
FROM sys.databases AS d
LEFT JOIN resource_pool AS rp
ON d.resource_pool_id = rp.pool_id
WHERE d.name = 'tempdb';
删除资源池绑定
若要在启用内存优化 TempDB 元数据的同时删除资源池绑定,请执行以下命令并重启服务:
ALTER SERVER CONFIGURATION
SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON;
禁用
若要禁用内存优化 TempDB 元数据,请执行以下命令并重启服务:
ALTER SERVER CONFIGURATION
SET MEMORY_OPTIMIZED TEMPDB_METADATA = OFF;
内存优化的 TempDB 元数据限制
启用或禁用内存优化 TempDB 元数据功能需要重启。
在某些情况下,您可能会观察到
MEMORYCLERK_XTP
内存分配管理器使用率较高,导致工作负荷出现内存不足错误。若要查看
MEMORYCLERK_XTP
管理器相对于所有其他内存管理器及目标服务器内存的内存使用情况,请执行以下查询:SELECT SUM(IIF(type = 'MEMORYCLERK_XTP', pages_kb, NULL)) / 1024. AS memoryclerk_xtp_pages_mb, SUM(IIF(type <> 'MEMORYCLERK_XTP', pages_kb, NULL)) / 1024. AS other_pages_mb, SUM(committed_target_kb) / 1024. AS committed_target_memory_mb FROM sys.dm_os_memory_clerks CROSS JOIN sys.dm_os_sys_info;
如果
MEMORYCLERK_XTP
内存较高,可以按如下方式缓解问题:- 将
tempdb
数据库绑定到限制内存优化 TempDB 元数据占用的资源池。 有关详细信息,请参阅 配置和使用内存优化的 tempdb 元数据。 - 系统存储过程可以定期执行,以释放
MEMORYCLERK_XTP
不再需要的内存。 有关详细信息,请参阅 sys.sp_xtp_force_gc (Transact-SQL)。
有关详细信息,请参阅 内存优化 tempdb 元数据(HkTempDB)内存不足错误。
- 将
使用 In-Memory OLTP 时,不允许单个事务访问多个数据库中的内存优化表。 因此,任何涉及用户数据库中内存优化表的读取或写入事务也不能访问
tempdb
同一事务中的系统视图。 如果发生这种情况,将收到错误 41317:A user transaction that accesses memory optimized tables or natively compiled modules cannot access more than one user database or databases model and msdb, and it cannot write to master.
此限制也适用于其他方案,即单个事务尝试访问多个数据库中的内存优化表。
例如,如果在包含内存优化表的用户数据库中查询 sys.stats 目录视图,则可能会收到错误 41317。 发生这种情况是因为查询尝试访问用户数据库中内存优化表和内存优化元数据中的
tempdb
统计信息数据。启用内存优化 TempDB 元数据时,以下示例脚本将生成此错误:
BEGIN TRAN; -- Create an In-memory OLTP transaction that accesses a system view in tempdb SELECT name FROM tempdb.sys.tables; -- An attempt to create an In-memory OLTP transaction in the user database fails INSERT INTO <user database>.<schema>.<memory-optimized table> VALUES (1); COMMIT TRAN;
注意
此限制不适用于临时表。 可以在访问用户数据库中内存优化表的同一事务中创建临时表。
针对系统目录视图的
READ COMMITTED
查询始终使用隔离级别。 启用内存优化的 TempDB 元数据后,针对系统目录视图的tempdb
查询将采用SNAPSHOT
隔离级别。 在任何情况下,“锁定提示”都不会被遵守。如果启用内存优化 TempDB 元数据,则无法在临时表上创建列存储索引。
- 因此,当启用内存优化 TempDB 元数据时,不支持将系统存储过程与
COLUMNSTORE
或COLUMNSTORE_ARCHIVE
数据压缩参数一起使用sp_estimate_data_compression_savings
。
- 因此,当启用内存优化 TempDB 元数据时,不支持将系统存储过程与
SQL Server 中的 tempdb 容量计划
为tempdb
确定适当的大小取决于许多因素。 这些因素包括使用的工作负荷和数据库引擎功能。
建议通过在测试环境中执行以下任务来分析 tempdb
空间消耗,可在其中重现典型工作负荷:
- 为
tempdb
文件启用自动增长。 所有tempdb
数据文件应具有相同的初始大小和自动增长配置。 - 重现工作负荷并监视
tempdb
空间使用。 - 如果使用定期 索引维护,请执行维护作业并监视
tempdb
空间。 - 使用前面步骤中已用的最大空间值来预测工作负荷总使用量。 为计划的并发活动调整此值,然后相应地设置
tempdb
的大小。
监视 tempdb 的使用
磁盘空间 tempdb
不足可能会导致重大中断和应用程序停机。 可以使用 sys.dm_db_file_space_usage 动态管理视图监视文件中使用的 tempdb
空间。
例如,下面的示例脚本展示:
- 可用空间(
tempdb
不考虑可用于tempdb
增长的可用磁盘空间)。 - 传统版本存储所占用的空间。
- 若要在启用
tempdb
加速数据库恢复时监视持久性版本存储(PVS)的大小,请参阅检查 PVS 的大小。
- 若要在启用
- 内部对象使用的空间。
- 用户对象使用的空间。
SELECT SUM(unallocated_extent_page_count) * 8.0 / 1024 AS tempdb_free_data_space_mb,
SUM(version_store_reserved_page_count) * 8.0 / 1024 AS tempdb_version_store_space_mb,
SUM(internal_object_reserved_page_count) * 8.0 / 1024 AS tempdb_internal_object_space_mb,
SUM(user_object_reserved_page_count) * 8.0 / 1024 AS tempdb_user_object_space_mb
FROM tempdb.sys.dm_db_file_space_usage;
若要在会话或任务级别监视页面分配或解除分配活动 tempdb
,可以使用 sys.dm_db_session_space_usage 和 sys.dm_db_task_space_usage 动态管理视图。 这些视图可帮助你识别使用大量 tempdb
空间的查询、临时表或表变量。
例如,使用以下示例脚本获取 tempdb
每个会话中所有当前正在运行的任务中内部对象分配和解除分配的空间:
SELECT session_id,
SUM(internal_objects_alloc_page_count) AS task_internal_objects_alloc_page_count,
SUM(internal_objects_dealloc_page_count) AS task_internal_objects_dealloc_page_count
FROM sys.dm_db_task_space_usage
GROUP BY session_id;
使用以下示例脚本查找在运行和完成任务中每个会话和请求的内部对象和用户对象的已分配空间和当前已消耗空间:
WITH tempdb_space_usage AS
(
SELECT session_id,
request_id,
user_objects_alloc_page_count + internal_objects_alloc_page_count AS tempdb_allocations_page_count,
user_objects_alloc_page_count + internal_objects_alloc_page_count - user_objects_dealloc_page_count - internal_objects_dealloc_page_count AS tempdb_current_page_count
FROM sys.dm_db_task_space_usage
UNION ALL
SELECT session_id,
NULL AS request_id,
user_objects_alloc_page_count + internal_objects_alloc_page_count AS tempdb_allocations_page_count,
user_objects_alloc_page_count + internal_objects_alloc_page_count - user_objects_dealloc_page_count - user_objects_deferred_dealloc_page_count - internal_objects_dealloc_page_count AS tempdb_current_page_count
FROM sys.dm_db_session_space_usage
)
SELECT session_id,
COALESCE(request_id, 0) AS request_id,
SUM(tempdb_allocations_page_count * 8) AS tempdb_allocations_kb,
SUM(IIF (tempdb_current_page_count >= 0, tempdb_current_page_count, 0) * 8) AS tempdb_current_kb
FROM tempdb_space_usage
GROUP BY session_id, COALESCE (request_id, 0)
ORDER BY session_id, request_id;