收缩数据库

数据库中的每个文件都可以通过删除未使用的页的方法来减小。尽管数据库引擎会有效地重新使用空间,但某个文件多次出现无需原来大小的情况后,收缩文件就变得很有必要了。数据和事务日志文件都可以减小(收缩)。可以成组或单独地手动收缩数据库文件,也可以设置数据库,使其按照指定的间隔自动收缩。

文件始终从末尾开始收缩。例如,如果有个 5 GB 的文件,并且在 DBCC SHRINKFILE 语句中将 target_size 指定为 4 GB,则数据库引擎将从文件的最后一个 1 GB 开始释放尽可能多的空间。如果文件中被释放的部分包含使用过的页,则数据库引擎先将这些页重新放置到文件的保留部分。只能将数据库收缩到没有剩余的可用空间为止。例如,如果某个 5 GB 的数据库有 4 GB 的数据,并且在 DBCC SHRINKFILE 语句中将 target_size 指定为 3 GB,则只能释放 1 GB。

自动数据库收缩

AUTO_SHRINK 数据库选项设置为 ON 后,数据库引擎将自动收缩具有可用空间的数据库。此选项可以使用 ALTER DATABASE 语句来进行设置。默认情况下,此选项设置为 OFF。数据库引擎会定期检查每个数据库的空间使用情况。如果某个数据库的 AUTO_SHRINK 选项设置为 ON,则数据库引擎将减少数据库中文件的大小。该活动在后台进行,并且不影响数据库内的用户活动。

将数据库设置为自动收缩

ALTER DATABASE (Transact-SQL)

手动数据库收缩

您可以使用 DBCC SHRINKDATABASE 语句或 DBCC SHRINKFILE 语句来手动收缩数据库或数据库中的文件。如果 DBCC SHRINKDATABASE 或 DBCC SHRINKFILE 语句无法回收日志文件中的所有指定空间,则该语句将发出信息性消息,指明必须执行什么操作以便释放更多空间。有关收缩日志文件的详细信息,请参阅收缩事务日志

在该过程中任意时间都可停止 DBCC SHRINKDATABASE 和 DBCC SHRINKFILE 操作,所有已完成工作都将保留。

在使用 DBCC SHRINKDATABASE 语句时,您无法将整个数据库收缩得比其初始大小更小。因此,如果数据库创建时的大小为 10 MB,后来增长到 100 MB,则该数据库最小只能收缩到 10 MB,即使已经删除数据库的所有数据也是如此。

但是,使用 DBCC SHRINKFILE 语句时,可以将各个数据库文件收缩得比其初始大小更小。必须对每个文件分别进行收缩,而不能尝试收缩整个数据库。

注意注意

备份数据库或事务日志的同时不能收缩数据库或事务日志。反过来,在尝试收缩数据库或事务日志时也不能创建数据库或事务日志备份。

收缩数据库

收缩数据或日志文件

收缩事务日志

事务日志文件可在固定的边界内收缩。日志中虚拟日志文件的大小决定着可能减小的大小。因此,不能将日志文件收缩到比虚拟日志文件还小。而且,日志文件收缩的增量大小与虚拟日志文件的大小相等。例如,一个大小为 1 GB 的事务日志文件可以由五个大小为 200 MB 的虚拟日志文件组成。收缩事务日志文件将删除未使用的虚拟日志文件,但至少会留下两个虚拟日志文件。由于此示例中的每个虚拟日志文件都是 200 MB,因此事务日志最小只能减小到 400 MB,且只能以 200 MB 的大小为增量减小。若要能够将事务日志文件减小得更小,可以创建一个较小的事务日志,并让其自动增长,而不要一次创建一个大型的事务日志文件。

DBCC SHRINKDATABASE 或 DBCC SHRINKFILE 操作会直接尝试将事务日志文件减小到所要求的大小(以四舍五入的值为准)。在收缩文件之前,应备份日志文件以减小逻辑日志的大小,并将不包含逻辑日志任何部分的虚拟日志标记为不活动。有关详细信息,请参阅收缩事务日志

最佳实践

当您计划收缩数据库或文件时,请考虑以下信息:

  • 在执行会产生许多未使用空间的操作(如截断表或删除表操作)后,执行收缩操作最有效。

  • 大多数数据库都需要一些可用空间,以供常规日常操作使用。如果反复收缩数据库并注意到数据库大小变大,则表明收缩的空间是常规操作所必需的。在这种情况下,反复收缩数据库是一种无谓的操作。

  • 收缩操作不会保留数据库中索引的碎片状态,通常还会在一定程度上增加碎片。例如,不应在重新生成索引后收缩数据库或数据文件。这是不要反复收缩数据库的另一个原因。

  • 除非有特定要求,否则不要将 AUTO_SHRINK 数据库选项设置为 ON。

基于行版本控制的隔离级别和收缩操作

在基于行版本控制的隔离级别下运行的事务可能会阻塞收缩操作。例如,在一次故障转移之后,伙伴可能分享相同的角色 - 主体或镜像。或者,当前主体服务器可能显示为镜像,而当前的镜像服务器显示为主体。出现这种情况时,DBCC SHRINKFILE 和 DBCC SHRINKDATABASE 操作会在第一个小时每五分钟将信息性消息(对于 SHRINKDATABASE 为 5202,对于 SHRINKFILE 为 5203)输出到 SQL Server 错误日志,之后每一个小时输出一次。有关详细信息,请参阅 DBCC SHRINKDATABASE (Transact-SQL)