收缩 tempdb 数据库
适用于: SQL Server Azure SQL 托管实例
本文讨论可用于收缩 SQL Server 中 tempdb
数据库的各种方法。
可以使用下列任一方法来更改 tempdb
大小。 本文介绍了前三个选项。 如果要使用 SQL Server Management Studio (SSMS),请按照收缩数据库中的说明进行操作。
方法 | 需要重启? | 详细信息 |
---|---|---|
ALTER DATABASE |
是 | 提供对默认 tempdb 文件(tempdev 和 templog )大小的完整控制。 |
DBCC SHRINKDATABASE |
否 | 在数据库级别运行。 |
DBCC SHRINKFILE |
否 | 允许收缩单个文件。 |
SQL Server Management Studio | 否 | 通过图形用户界面收缩数据库文件。 |
注解
默认情况下,tempdb
数据库配置为根据需要自动增长。 因此,此数据库可能会意外地增长到大于所需大小的大小。 较大 tempdb
数据库大小不会对 SQL Server 的性能产生不利影响。
SQL Server 启动时,tempdb
使用数据库的副本重新创建 model
,而 tempdb
重置为其上次配置的大小。 配置的大小是使用文件大小更改操作(例如使用 MODIFY FILE
选项的 ALTER DATABASE
,或者 DBCC SHRINKFILE
或 DBCC SHRINKDATABASE
语句)设置的最后一个显式大小。 因此,除非必须使用不同的值或立即处理大型 tempdb
数据库,否则可以等待 SQL Server 服务的下一次重启以缩减大小。
tempdb
活动正在进行时,可以收缩 tempdb
。 但是,可能会遇到其他错误,例如阻止、死锁等,从而阻碍收缩完成。 因此,为了确保成功收缩 tempdb
,我们建议在服务器处于单用户模式或停止所有 tempdb
活动时执行此操作。
SQL Server 只记录 tempdb
事务日志中足够的信息来回滚事务,但在数据库恢复期间不会重做事务。 此功能提高了 INSERT
中 tempdb
语句的性能。 此外,无需记录信息以重做任何事务,因为 tempdb
每次重新启动 SQL Server 时都会重新创建。 因此,它没有要前滚或回滚的事务。
有关管理和监视 tempdb
的详细信息,请参阅容量规划和监视 tempdb 使用情况。
使用 ALTER DATABASE 命令
注意
此命令仅对默认 tempdb
逻辑文件 tempdev
和 templog
执行。 如果更多文件添加到 tempdb
中,则可以在重启 SQL Server 即服务后将其收缩。 所有 tempdb
文件都在启动期间重新创建。 但是,它们为空,可以删除。 如果要删除 tempdb
中其他文件,则使用包含 REMOVE FILE
选项的 ALTER DATABASE
命令。
此方法要求重启 SQL Server。
停止 SQL Server。
在命令提示符下,以最低配置模式启动实例。 为此,请按照下列步骤进行操作:
在命令提示符处,切换到安装 SQL Server 的文件夹(替换以下示例中的
<VersionNumber>
和<InstanceName>
):cd C:\Program Files\Microsoft SQL Server\MSSQL<VersionNumber>.<InstanceName>\MSSQL\Binn
如果实例是 SQL Server 的命名实例,请运行以下命令(替换以下示例中的
<InstanceName>
):sqlservr.exe -s <InstanceName> -c -f -mSQLCMD
如果实例是 SQL Server 的默认实例,请运行以下命令:
sqlservr -c -f -mSQLCMD
注意
参数
-c
和-f
会导致 SQL Server 以最小配置模式启动,tempdb
数据文件的大小为 1 MB,日志文件的大小为 0.5 MB。 参数-mSQLCMD
可防止 sqlcmd 以外的任何其他应用程序接管单用户连接。
使用 sqlcmd 连接到 SQL Server 实例,然后运行以下 Transact-SQL 命令。 替换
<target_size_in_MB>
为所需的大小:ALTER DATABASE tempdb MODIFY FILE (NAME = 'tempdev', SIZE = <target_size_in_MB>); ALTER DATABASE tempdb MODIFY FILE (NAME = 'templog', SIZE = <target_size_in_MB>);
停止 SQL Server。 为此,请按命令提示符窗口的
Ctrl+C
,重启 SQL Server 即服务,然后验证tempdb.mdf
和templog.ldf
文件的大小。
使用 DBCC SHRINKDATABASE 命令
DBCC SHRINKDATABASE
接收参数 target_percent
。 数据库收缩后的数据库文件中所需的剩余可用空间百分比。 如果使用 DBCC SHRINKDATABASE
,可能需要重启 SQL Server。
使用
sp_spaceused
存储过程确定tempdb
中当前正在使用的空间。 然后,计算要用作DBCC SHRINKDATABASE
参数的剩余可用空间百分比。 此计算基于所需的数据库大小。注意
在某些情况下,可能需要执行
sp_spaceused @updateusage = true
以重新计算所使用的空间并获取更新的报告。 有关详细信息,请参阅 sp_spaceused。请考虑以下示例:
假设
tempdb
有两个文件:主数据文件 (tempdb
.mdf) 为 1,024 MB,日志文件 (tempdb.ldf
) 为 360 MB。 假设sp_spaceused
报告主数据文件包含 600 MB 的数据。 此外,假设你想要将主数据文件收缩到 800 MB。 计算收缩后剩余可用空间的所需百分比:800 MB - 600 MB = 200 MB。 现在,将 200 MB 除以 800 MB = 25%,这就是你的target_percent
。 事务日志文件相应地收缩,在数据库收缩后保留 25% 或 200 MB 的可用空间。使用 SSMS、Azure Data Studio 或 sqlcmd 连接到 SQL Server,然后运行以下 Transact-SQL 命令。 将
<target_percent>
替换为所需的百分比:DBCC SHRINKDATABASE (tempdb, '<target_percent>');
tempdb
上的 DBCC SHRINKDATABASE
命令存在限制。 数据和日志文件的目标大小不能小于创建数据库时指定的大小,也不能小于使用文件大小更改操作(例如使用 MODIFY FILE
选项的 ALTER DATABASE
)显式设置的最后一个大小。 DBCC SHRINKDATABASE
的另一个限制是参数 target_percentage
的计算及其对所用当前空间的依赖。
使用 DBCC SHRINKFILE 命令
使用 DBCC SHRINKFILE
命令收缩各个 tempdb
文件。 DBCC SHRINKFILE
提供的灵活性比 DBCC SHRINKDATABASE
更高,因为你可以在单个数据库文件上使用,而不会影响属于同一数据库的其他文件。 DBCC SHRINKFILE
接收 target_size
参数。 这是数据库文件所需的最终大小。
确定主数据文件 (
tempdb.mdf
)、日志文件 (templog.ldf
) 和添加到tempdb
的其他文件所需的大小。 确保文件中使用的空间小于或等于所需的目标大小。使用 SSMS、Azure Data Studio 或 sqlcmd 连接到 SQL Server,然后针对要收缩的特定数据库文件运行以下 Transact-SQL 命令。 替换
<target_size_in_MB>
为所需的大小:USE tempdb; GO -- This command shrinks the primary data file DBCC SHRINKFILE (tempdev, '<target_size_in_MB>'); GO -- This command shrinks the log file, examine the last paragraph. DBCC SHRINKFILE (templog, '<target_size_in_MB>'); GO
DBCC SHRINKFILE
的优点是可以将文件大小缩减到小于其原始大小。 可以在任何数据或日志文件发出 DBCC SHRINKFILE
。 不能使数据库小于 model
数据库的大小。
运行收缩操作时出现错误 8909
如果 tempdb
正在使用,并且你尝试使用 DBCC SHRINKDATABASE
或 DBCC SHRINKFILE
命令缩小它,则可能会收到类似于以下内容的消息,具体取决于所使用的 SQL Server 版本:
Server: Msg 8909, Level 16, State 1, Line 1 Table error: Object ID 0, index ID -1, partition ID 0, alloc unit ID 0 (type Unknown), page ID (6:8040) contains an incorrect page ID in its page header. The PageId in the page header = (0:0).
此错误并不代表 tempdb
中任何真正的损坏。 但是,可能有其他原因导致类似错误 8909 的物理数据损坏错误,这些原因包括 I/O 子系统问题。 因此,如果错误发生在收缩操作外部,则应进行更多调查。
尽管将 8909 消息返回到应用程序或正在执行收缩操作的用户,但收缩操作不会失败。