【MSSQL】shrinkdatabase和shrinkfile区别

本文详细介绍了SQL Server中的DBCC SHRINKDATABASE和DBCC SHRINKFILE命令,分别用于收缩数据库和文件。内容涵盖两者区别、参数说明、使用场景以及注意事项,帮助理解如何有效地管理和调整数据库空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

具体内容请看 SQL 2005技术内幕之存储引擎第4章

DBCC SHRINKFILE不能将文件大小缩小到比存储数据所需空间还小的尺寸.
DBCC SHRINKDATABASE不能收缩到比MODEL数据库还小,并且也不能将一个文件收缩到比其最小还小.
TRUNCATEONLY能使一个数据文件中的所以为被使用空间都被释放给操作系统,但不会试图重新分配数据行到未分配的页面.

DBCC SHRINKDATABASE

收缩指定数据库中的数据文件大小。

语法

DBCC SHRINKDATABASE

    ( database_name [ , target_percent ]

        [ , { NOTRUNCATE | TRUNCATEONLY } ] 

    )

参数

database_name

是要收缩的数据库名称。数据库名称必须符合标识符的规则。有关更多信息,请参见使用标识符。 

target_percent

是数据库收缩后的数据库文件中所要的剩余可用空间百分比。 

NOTRUNCATE

导致在数据库文件中保留所释放的文件空间。如果未指定,将所释放的文件空间释放给操作系统。 

TRUNCATEONLY

导致将数据文件中的任何未使用的空间释放给操作系统,并将文件收缩到上一次所分配的大小,从而减少文件大小,而不移动任何数据。不试图重新定位未分配页的行。使用 TRUNCATEONLY 时,忽略 target_percentis。

注释

Microsoft® SQL Server™ 可收缩: 

特定数据库的所有数据和日志文件。执行 DBCC SHRINKDATABASE。

一次一个特定数据库中的数据或日志文件。执行 DBCC SHRINKFILE。 

DBCC SHRINKDATABASE 以每个文件为单位对数据文件进行收缩。然而,DBCC SHRINKDATABASE 在对日志文件进行收缩时,看起来好像所有的日志文件都存在于一个连续的日志池中。 

假设名为 mydb 的数据库有两个数据文件和两个日志文件。这些数据文件和日志文件大小都为 10 MB。第一个数据文件包含 6 MB 数据。

对于每个文件,SQL Server 计算目标大小,即要收缩文件到的大小。当用 target_percent 指定 DBCC SHRINKDATABASE 时,SQL Server 计算的目标大小是收缩后文件中的 target_percent 可用空间大小。例如,如果指定按 target_percent 为 25 收缩 mydb。SQL Server 计算的该文件的目标大小为 8 MB(6 MB 数据加上 2 MB 可用空间)。因此,SQL Server 将任何数据从数据文件的最后 2 MB 中移动到数据文件前 8 MB 的可用空间中,然后对该文件进行收缩。

假设 mydb 的第一个数据文件包含 7 MB 的数据。若将 target_percent 指定为 30,则允许将该数据文件收缩到所要的可用百分比 30。然而,若将 target_percent 指定为 40,就不会收缩该数据文件,因为 SQL Server 不能将文件收缩到比数据当前占有的空间还小的程度。也可以从另一个角度考虑这个问题:40% 要求的可用空间 + 70% 完整的数据文件(10 MB 中的 7 MB)大于 100%。因为所要求的可用百分比加上数据文件占用的当前百分比大于 100%(多出 10%),所以任何大于 30 的 target_size 都不会收缩该数据文件。 

对于日志文件,SQL Server 使用 target_percent 以对整个日志的目标大小进行计算;因此,target_percent 是收缩操作后日志中的可用空间大小。之后,整个日志的目标大小可以解释为每个日志文件的目标大小。DBCC SHRINKDATABASE 尝试立即将每个物理日志文件收缩到其目标大小。如果虚拟日志中的所有逻辑日志部分都没有超出日志文件的目标大小,则该文件将成功截断,DBCC SHRINKDATABASE 完成且不显示任何消息。然而,如果虚拟日志中的逻辑日志部分超出其目标大小,则 SQL Server 释放尽可能多的空间并发出一条消息。该消息告诉您需要执行什么操作来移动文件末尾超出虚拟日志的逻辑日志部分。执行完该操作后,可以重新发出 DBCC SHRINKDATABASE 命令以释放剩余的空间。有关收缩事务日志的更多信息,请参见收缩事务日志。

因为日志文件只能收缩到虚拟日志文件边界,所以不可能将日志文件收缩到比虚拟日志文件更小(即使现在没有使用该文件)。例如,可以将数据库的 1 GB 日志文件收缩到只有 128 MB。有关截断的更多信息,请参见截断事务日志。有关确定虚拟日志文件大小的更多信息,请参见虚拟日志文件。 

由 DBCC SHRINKDATABASE 计算的数据和日志文件的目标大小始终不小于文件的最小大小。文件的最小大小是在文件最初创建时指定的大小,或是上一次用更改文件大小的操作(如用带有 MODIFY FILE 选项的 ALTER DATABASE 或 DBCC SHRINKFILE)显式设置的大小。例如,如果在执行 CREATE DATABASE 时,将 mydb 的所有数据和日志文件大小都指定为 10 MB,则每个文件的最小大小都为 10 MB。DBCC SHRINKDATABASE 不能收缩任何小于 10 MB 的文件。如果使用带有 MODIFY FILE 选项的 ALTER DATABASE 将其中的一个文件显示增长到 20 MB,则该文件新的最小大小为 20 MB。若要将文件大小收缩到小于其最小大小,请使用 DBCC SHRINKFILE 并指定新大小。执行 DBCC SHRINKFILE 会将文件的最小大小更改为所指定的新大小。

在使用数据文件时,DBCC SHRINKDATABASE 有 NOTRUNCATE 和 TRUNCATEONLY 选项。如果为日志文件指定这两个选项,则将忽略这两个选项。DBCC SHRINKDATABASE 不带任何选项等价于 DBCC SHRINKDATABASE 带有 NOTRUNCATE 选项,后面还要跟着带有 TRUNCATEONLY 选项的 DBCC SHRINKDATABASE。

不论是否指定 target_percent,NOTRUNCATE 选项都执行 DBCC SHRINKDATABASE 的实际数据移动操作(包括将分配页从文件的末尾移动到文件前面的未分配页)。然而,文件末尾的可用空间不会返回给操作系统,文件的物理大小也不会更改。因此,如果指定 NOTRUNCATE 选项,数据文件好像没有收缩。例如,假设再次使用 mydb 数据库,该 mydb 有两个数据文件和两个日志文件。第二个数据文件和第二个日志文件的大小都为 10 MB。执行 DBCC SHRINKDATABASE mydb NOTRUNCATE 时,Microsoft SQL Server 将数据从数据文件的后面几页移动到前面几页中。而文件的大小仍然为 10 MB。

TRUNCATEONLY 选项将文件末尾的所有可用空间收回给操作系统。然而,TRUNCATEONLY 在文件内不执行任何页移动操作。指定的文件只能收缩到上一次分配的大小。如果使用 TRUNCATEONLY 选项指定 target_percent,则忽略后者。

所生成的数据库不能比 model 数据库更小。

要收缩的数据库不必在单用户模式下;其他的用户仍可以在数据库收缩时对其进行工作。这也包括系统数据库。

结果集

下表描述结果集内的列。

列名 描述 

DbId SQL Server 试图收缩的文件的数据库标识号。 

FileId SQL Server 试图收缩的文件的文件标识号。 

CurrentSize 文件当前占用的 8KB 页数。 

MinimumSize 文件可以占用的最小 8KB 页数。这与文件的最小大小或最初创建时的大小相对应。 

UsedPages 文件当前使用的 8KB 页数。 

EstimatedPages SQL Server 估计文件能够收缩到的 8KB 页数。 


DBCC SHRINKFILE

收缩相关数据库的指定数据文件或日志文件大小。

语法

DBCC SHRINKFILE

    ( { file_name | file_id }

        { [ , target_size ]

            | [ , { EMPTYFILE | NOTRUNCATE | TRUNCATEONLY } ] 

        }

    )

参数

file_name

是已收缩文件的逻辑名称。文件名必须符合标识符的规则。有关更多信息,请参见使用标识符。 

file_id

是要收缩的文件的标识 (ID) 号。若要获得文件 ID,请使用 FILE_ID 函数或在当前数据库中搜索 sysfiles。

target_size

是用兆字节表示的所要的文件大小(用整数表示)。如果没有指定,DBCC SHRINKFILE 将文件大小减少到默认文件大小。

如果指定 target_size,DBCC SHRINKFILE 将试图将文件收缩到指定大小。将要释放的文件部分中的已使用页将重新定位到保留的文件部分中的可用空间。例如,如果数据文件为 10MB,则带有 target_size 为 8 的 DBCC SHRINKFILE 将导致文件最后 2 MB 中所有已用页重新分配到文件前 8 MB 中的任何可用槽中。DBCC SHRINKFILE 不会将文件收缩到小于存储文件中的数据所需要的大小。例如,如果使用 10MB 数据文件中的7 MB,带有 target_size 为 6 的 DBCC SHRINKFILE 语句只能将该文件收缩到 7 MB,而不能收缩到 6 MB。

EMPTYFILE

将所有数据从指定文件中迁移到同一文件组中的其它文件。Microsoft® SQL Server™ 不再允许将数据放在用于 EMPTYFILE 选项的文件上。该选项允许使用 ALTER DATABASE 语句除去文件。

NOTRUNCATE

导致将释放的文件空间保留在文件中。

当与 target_size 一起指定 NOTRUNCATE 时,释放的空间不会释放给操作系统。DBCC SHRINKFILE 的唯一影响是将已使用的页从 target_size 行上面重新定位到文件的前面。当未指定 NOTRUNCATE 时,所有释放的文件空间返回给操作系统。

TRUNCATEONLY

导致文件中的任何未使用的空间释放给操作系统,并将文件收缩到上一次分配的大小,从而减少文件大小,而不移动任何数据。不尝试将行重新定位到未分配页。如果使用 TRUNCATEONLY,将忽略 target_size。

注释

DBCC SHRINKFILE 适用于当前数据库中的文件。将上下文切换到数据库,以发出引用该特定数据库中文件的 DBCC SHRINKFILE 语句。有关更改当前数据库的更多信息,请参见 USE。 

所生成的数据库不能比 model 数据库更小。

使用 DBCC SHRINKFILE 以将文件减小到比其最初创建时更小。之后,文件的最小大小重置为新指定的大小。

若要删除在文件中可能出现的任何数据,请在执行ALTER DATABASE 之前执行 DBCC SHRINKFILE('file_name', EMPTYFILE)。

要收缩的数据库不必在单用户模式下;收缩文件时,同时其他用户可以在数据库中工作。不必在单用户模式下运行 SQL Server 以对系统数据库进行收缩。

对于日志文件,SQL Server 使用 target_size 以计算整个日志的目标大小;因此,target_size 是收缩操作完成后日志中的可用空间大小。之后,整个日志的目标大小可以解释为每个日志文件的目标大小。DBCC SHRINKFILE 尝试立即将每个物理日志文件收缩至其目标大小。如果虚拟日志中的所有逻辑日志部分都没有超出日志文件的目标大小,该文件将成功截断,DBCC SHRINKFILE 完成且不显示任何消息。然而,如果虚拟日志中的逻辑日志部分超出目标大小,则 SQL Server 释放尽可能多的空间并发出一条消息。该信息告诉您需要执行什么操作来移动文件末尾超出虚拟日志的逻辑日志部分。执行完该操作后,可以重新发出 DBCC SHRINKFILE 命令以释放剩余的空间。有关收缩事务日志的更多信息,请参见收缩事务日志。

因为日志文件只能收缩到虚拟日志文件边界,所以不可能将日志文件收缩到比虚拟日志文件更小(即使现在没有使用该文件)。例如,可以将数据库的 1 GB 日志文件收缩到只有 128 MB。有关截断的更多信息,请参见截断事务日志。有关确定虚拟日志文件大小的更多信息,请参见虚拟日志文件。 

结果集

下表描述结果集内的列。

列名 描述 

DbId SQL Server 试图收缩的文件的数据库标识号。 

FileId SQL Server 试图收缩的文件的文件标识号。 

CurrentSize 文件当前占用的 8KB 页数。 

MinimumSize 文件可以占用的最小 8KB 页数。这与文件的最小大小或最初创建时的大小相对应。 

UsedPages 文件当前使用的 8KB 页数。 

EstimatedPages SQL Server 估计文件能够收缩到的 8KB 页数。 

权限

DBCC SHRINKFILE 权限默认授予 sysadmin 固定服务器角色或 db_owner 固定数据库角色的成员且不可转让。

示例

下例将 UserDB 用户数据库中名为 DataFil1 的文件收缩到 7 MB。

USE UserDB

GO

DBCC SHRINKFILE (DataFil1, 7)

GO


 

<think>我们正在讨论SQL Server中的DBCC SHRINKDATABASE命令,该命令用于收缩特定数据库的数据日志文件的大小。根据用户提供的引用,我们可以整合信息并给出使用方法注意事项。首先,引用[1][2]都提到了DBCCSHRINKDATABASE的基本用法。引用[1]指出,如果不指定任何选项,则相当于先执行NOTRUNCATE再执行TRUNCATEONLY。引用[2]提到,要收缩单个文件,应使用DBCC SHRINKFILE命令。 引用[5]提醒我们,在收缩数据库之前,空间使用统计信息可能不是实时更新的,因此建议先更新统计信息或注意可能的不准确情况。此外,引用[3][4]虽然与DBCC SHRINKDATABASE不直接相关,但提醒我们在进行数据库维护操作时,确保数据库的完整性很重要(如使用DBCC CHECKDB)。现在,我们将按照用户要求,用中文回答,并遵循格式要求。 ###DBCC SHRINKDATABASE命令`DBCCSHRINKDATABASE`用于收缩指定数据库的数据文件日志文件的大小。其基本语法如下:```sqlDBCC SHRINKDATABASE(database_name |database_id |0[ ,target_percent ][ ,{ NOTRUNCATE |TRUNCATEONLY }]) ```参数说明: -`database_name |database_id|0`:数据库名称、ID或0(表示当前数据库)。- `target_percent`:可选,收缩后数据库文件中所需的剩余可用空间百分比。 -`NOTRUNCATE`:将释放的文件空间保留在文件中,而不是返还给操作系统。此选项只适用于数据文件。- `TRUNCATEONLY`:将文件末尾的所有可用空间释放给操作系统,但不在文件内部移动任何数据。使用此选项时,`target_percent`被忽略。####注意事项1.**空间统计信息更新**:在执行收缩操作之前,建议先更新空间使用统计信息。可以使用`DBCC UPDATEUSAGE`来更新统计信息,以避免因统计信息不准确而导致的错误收缩(引用[5])。 2. **性能影响**:收缩操作会导致大量的I/O索引碎片。因此,应避免在数据库繁忙时执行,且收缩后建议重建索引。3.**日志文件管理**:对于日志文件,通常通过备份事务日志来释放空间,而不是频繁收缩。收缩日志文件可能会导致日志文件增长事件再次发生,影响性能。4.**文件末尾空间**:收缩操作只能释放文件末尾的未使用空间。如果文件中间有未使用空间(如删除数据后),收缩操作需要重新组织数据页,这可能会非常耗时。5.**自动收缩**:不建议将数据库设置为自动收缩(`AUTO_SHRINK`),因为这可能导致性能问题。6.**替代方法**:如果只需要收缩单个文件,使用`DBCC SHRINKFILE`更合适(引用[2])。7.**操作等价性**:运行`DBCC SHRINKDATABASE`而不指定`NOTRUNCATE`或`TRUNCATEONLY`选项,等价于先执行带`NOTRUNCATE`的操作,然后再执行带`TRUNCATEONLY`的操作(引用[1])。 ####示例收缩当前数据库,保留10%的可用空间:```sqlDBCC SHRINKDATABASE (0,10); ```收缩数据库`MyDB`,并释放所有未使用的空间(使用`TRUNCATEONLY`):```sqlDBCC SHRINKDATABASE (MyDB, TRUNCATEONLY); ```###相关问题1.如何更新数据库的空间使用统计信息? 2.收缩数据库后,如何检查索引碎片情况? 3.为什么收缩日志文件通常不推荐?4.如何收缩单个数据库文件?5.使用`DBCCSHRINKDATABASE`后,数据库文件的大小没有变化,可能的原因是什么?[^1]:[MSDN]DBCCSHRINKDATABASE(Transact-SQL)[ZH-CN] [^2]: [MSDN] DBCC SHRINKDATABASE (Transact-SQL) [EN-US] [^5]: DBCC--SHRINKDATABASE</think>### DBCC SHRINKDATABASE 命令详解 `DBCC SHRINKDATABASE` 是 SQL Server 中用于收缩数据库大小的命令,通过释放未使用的空间来减小数据文件日志文件的物理大小。以下是使用方法关键注意事项: #### 语法格式 ```sql DBCC SHRINKDATABASE ( database_name | database_id | 0 [ , target_percent ] [ , { NOTRUNCATE | TRUNCATEONLY } ] ) ``` #### 参数说明 1. **database_name | database_id | 0** - 目标数据库名称、ID 或 `0`(表示当前数据库) 2. **target_percent**(可选) - 收缩后文件中的剩余可用空间百分比(例如 `10` 表示保留10%空闲空间) 3. **操作模式**(可选) - `NOTRUNCATE`:释放的空间保留在文件中,不返还操作系统 - `TRUNCATEONLY`:仅释放文件末尾未用空间,不移动数据页 #### 使用示例 1. 收缩当前数据库,保留15%空闲空间: ```sql DBCC SHRINKDATABASE (0, 15); ``` 2. 仅释放未用空间到操作系统(不移动数据): ```sql DBCC SHRINKDATABASE (MyDB, TRUNCATEONLY); ``` #### 关键注意事项 1. **空间统计滞后问题** 收缩前建议先更新空间统计信息,避免因统计不准确导致无效操作[^5]: ```sql EXEC sp_updatestats; DBCC UPDATEUSAGE(0); ``` 2. **性能影响** - 收缩操作会导致大量 I/O 索引碎片,应在低峰期执行 - 收缩后需重建索引:`ALTER INDEX ALL ON TableName REBUILD` 3. **日志文件特殊处理** - 日志文件需先备份再收缩: ```sql BACKUP LOG MyDB TO DISK='...'; DBCC SHRINKFILE (MyDB_Log, 100); -- 收缩到100MB ``` 4. **替代方案建议** - 收缩单个文件更推荐使用 `DBCC SHRINKFILE`[^2] - 避免频繁收缩,建议配置文件自动增长(`AUTO_GROWTH`) 5. **操作限制** - 无法收缩只读数据库 - 内存优化表不支持收缩 - 操作期间会阻塞并发 DDL 语句 #### 最佳实践 1. 收缩前检查空间使用: ```sql EXEC sp_spaceused; ``` 2. 优先收缩日志文件(通常回收空间更多) 3. 操作后验证数据库完整性[^3]: ```sql DBCC CHECKDB (MyDB) WITH NO_INFOMSGS; ``` > **重要警告**:频繁收缩数据库会导致文件碎片化,反而降低性能。建议仅在磁盘空间不足时使用,并配合定期索引维护[^1][^5]。 ### 相关问题 1. DBCC SHRINKDATABASE DBCC SHRINKFILE 的主要区别是什么? 2. 如何避免数据库文件频繁增长后需要手动收缩? 3. 收缩数据库操作导致事务日志暴增该如何处理? 4. 能否在数据库在线时执行收缩操作?有什么风险? 5. 收缩操作后如何验证数据库的物理完整性? [^1]: [MSDN] DBCC SHRINKDATABASE (Transact-SQL) [ZH-CN] [^2]: [MSDN] DBCC SHRINKDATABASE (Transact-SQL) [EN-US] [^3]: DBCC CHECKDB 官方文档说明 [^5]: DBCC SHRINKDATABASE 空间统计注意事项
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值