我有一个生产 SQL Server 2008,其中 8 TB 分布在多个数据库上。我已经删除了每个数据库中大约 85% 的数据,并且必须恢复磁盘空间。所有 USED_SPACE 的最终 SUM 将为 1.2 TB。
此 SHRINKFILE 进程必须适合每个数据库的 7 小时维护窗口。
但是,每个上的 DBCC SHRINKFILE 都需要很多小时才能运行。例如,将 800 GB 的数据库缩小到 120 GB 需要 15 多个小时。
不幸的是,这超出了我的维护窗口,我被迫终止进程,希望数据库不会损坏(随后的 DBCC CHECKDB 显示它们很好)。
我可以看到 DBCC SHRINKFILE 没有充分利用可用的磁盘 I/O 和 CPU 资源。
例如,可以在几个小时内将完整大小的数据库文件从一个磁盘复制到另一个磁盘,但 SHRINKFILE 过程需要相当长的时间。
注意:数据库都设置为 SIMPLE 恢复模式并且 AUTO_SHRINK 关闭。
是的,我看到很多人说永远不要这样做,因为它会破坏索引——我确实计划在 SHRINKFILE 完成时重建索引。
有什么方法可以提高 SHRINKFILE 命令的优先级或任何替代解决方案?以下是我正在考虑的一些选项:
- 在运行 SHRINKFILE 之前,在同一会话中将 DEADLOCK_PRIORITY 设置为高。
(但我怀疑这会有所帮助。) - 创建一个新数据库并逐表复制所有数据。
解决办法是留出额外的空间。
缩小 MDF 文件时,如果我留下一些未使用的空间(不要删除所有未使用的空间),那么它会更快地完成。
例如:如果一个 3TB 的数据库只使用了 200MB,将其缩小到 200MB 将需要很长时间。但是,如果我将它缩小到 300MB,那么缩小过程会快得多。
我猜 SQL 必须将数据碎片整理到极致才能删除所有未使用的空间。然而,通过留下额外的空间,它必须只重新组织较大的数据部分或以其他方式调整文件指针以适应。