Inf*_*o23 4 sql-server-2008-r2
我是一个偶然的 DBA。我们有一个托管 10 个数据库的 sql 集群。突然间,其中一个数据库的大小从 100GB 急剧增加到 250GB。当我们检查数据文件时,它的大小在过去几天中增长了两倍多。我们识别了这些表并截断了数据并删除了 130GB 的数据。数据文件仍然显示 250GB。我们如何回收空间?
非常感谢您的帮助。
首先,您确定数据增长不会再次发生吗?如果有一个现实的机会它会并且空白空间不会伤害您,请留下它,不要缩小数据库。
但是,如果您确定要减小数据文件大小,那么您应该了解数据文件缩小的陷阱:
WITH TRUNCATEONLY
选项,如果您只是删除文件末尾的可用空间)我参考了 Paul Randal 在他的文章“为什么不应该收缩数据文件”中的建议(阅读整篇文章以清楚了解索引碎片会发生什么):
我喜欢推荐的方法如下:
- 创建一个新的文件组
- 使用
CREATE INDEX … WITH (DROP_EXISTING = ON) ON
语法将所有受影响的表和索引移动到新文件组中,以同时移动表并从中删除碎片- 删除您无论如何要缩小的旧文件组(如果它是主要文件组,则将其缩小)
基本上,您需要先提供更多空间,然后才能缩小旧文件,但这是一种更简洁的机制。
如果您绝对别无选择并且必须运行数据文件收缩操作,请注意您将导致索引碎片,并且如果它会导致性能问题,您应该在事后采取措施将其删除。删除索引碎片而不导致数据文件再次增长的唯一方法是使用
DBCC INDEXDEFRAG
或ALTER INDEX … REORGANIZE
。这些命令只需要一个 8KB 页的额外空间,而不需要在索引重建操作的情况下构建一个全新的索引。底线 - 尽量避免不惜一切代价运行数据文件收缩!
我建议您使用 DBCC SHRINKFILE()。您可以使用此链接的答案中的查询检查文件的可用空间如何确定 SQL 数据库文件中的已用/可用空间?
如果您只有一个数据文件和一个日志文件,它可能只是文件 #1 和文件 #2。您必须将文件编号传递给 SHRINKFILE 命令。这不是必需的,但我建议您小批量进行(一次可能是 1 或 10 GB)。因此,如果您有一个 250 GB 的数据文件,但数据只有 100 GB,请执行以下操作
DBCC SHRINKFILE(1, 240000)
GO
DBCC SHRINKFILE(1, 230000)
GO
DBCC SHRINKFILE(1, 220000)
GO
...
Run Code Online (Sandbox Code Playgroud)
我会留下一定量的可用空间,所以不要一直降到 100 GB。为文件中的工作操作留出 10 或 20 GB 的空闲空间。
收缩文件不应阻塞。如果其他操作正在处理数据文件,则它通常会暂停,如果您正在缩小批处理可能需要很长时间才能完成的大块。
如果部分未使用的空间来自日志文件(通常是文件 #2),那么您可以在备份后一次性将其缩小(如果您处于完全恢复模式)。使用 DBCC SQLPERF(logspace) 检查已使用的日志空间和已使用的百分比。如果使用的百分比很低,那么您可以毫无问题地缩小它。只需使用 DBCC SHRINKFILE(2, 500) 将日志缩小到 500 MB 文件(选择您认为最适合常规操作使用的任何大小)