SHRINKFILE 最佳实践和经验

Csa*_*oth 6 sql-server-2005 sql-server best-practices shrink

序言:总的来说,这是一个很大的禁忌,但相信我,在真正需要空间的情况下,这种情况很少见。例如 Express Edition 限制为 10GB。想象一下,您发现通过数据类型转换(blob 列)可以释放大量空间。但在那之后,DB 文件的大小仍然和我们知道的一样,10GB 的限制也没有神奇地改变。所以需要某种收缩。那是一个例子。

在我的测试环境中,我执行了:

DBCC SHRINKFILE (DBFile, NOTRUNCATE)
DBCC SHRINKFILE (DBFile, TRUNCATEONLY)
Run Code Online (Sandbox Code Playgroud)

这确实有效(我知道这会最大限度地减少可用空间,在现实世界中我会留下可用空间)。花了很多小时才完成。正如我们所知,它是一个单线程进程奇怪的行为 DBCC Shrinkfile,“它作为一系列非常小的系统事务工作,因此没有什么可回滚的。” - 保罗兰达尔http://www.sqlservercentral.com/Forums/Topic241295-5-1.aspx。我们也知道它搞乱了索引碎片时间http://www.mssqltips.com/sqlservertip/2055/issues-with-running-dbcc-shrinkfile-on-your-sql-server-data-files/和我可以确认。尽管在http://www.karaszi.com/SQLServer/info_dont_shrink.asp 中有描述,但我没有遇到日志文件增长

我发布了一些INDEX REBUILDREORGANIZE而那些在几秒钟内就完成了。

我的问题:

  1. 如果我可以在收缩后几秒钟内修复索引碎片,那么收缩有什么大不了的?我不明白。在 DBA stackexchange 上,“收缩”主题 ( https://dba.stackexchange.com/tags/shrink/info ) 说“几乎是您可以对 SQL Server 数据库做的最糟糕的事情。简而言之:它牺牲了性能来获得空间。” plus 指的是另一篇关于它的流行文章。但是索引碎片是可以修复的。
  2. 为什么我没有遇到任何日志文件增长?
  3. 如果在空间释放操作后首先重建索引会怎样。可以代替第一个DBCC SHRINKFILE (DBFile, NOTRUNCATE)所以我只需要DBCC SHRINKFILE (DBFile, TRUNCATEONLY)吗?我有一种感觉,两者在不同的逻辑层面上工作,但我不得不问这个。

底线:我保证我不会定期收缩或做任何事情。但这是一个上限被击中并需要收缩的情况。


回答我的第二个问题:我没有遇到事务日志文件增长,因为我在开发人员测试环境中摆弄。事务日志文件会在生产环境中增长(假设完全恢复模型)。您也应该在您的测试环境中模仿它。tr 日志文件的增长实际上大于您可以在数据库文件中释放的空间。最后,您不仅要收缩数据库文件,还要收缩事务日志(如何以及何时这样做取决于恢复模型)。我看到的生产环境有如此严重的索引碎片,它可以变得更好。我的脚本重新索引每个碎片级别高于 30% 的索引。

为了应对增长,您可能必须在进行一生一次的转换时从完全恢复切换到简单。但这会破坏备份链。


回答我的第三个问题:在 DB 文件收缩后进行重新索引/索引重建,因为收缩会弄乱索引碎片。

我还没有试验过所有这些如何影响查询统计信息。


脚本重新索引:见实施例d的TechNet sys.dm_db_index_physical_stats(的Transact-SQL) 。一篇关于增量收缩的文章,会引出其他有价值的内容:http : //www.mssqltips.com/sqlservertip/3178/incrementally-shrinking-a-large-sql-server-data-file-using-powershell

Aar*_*and 14

如果你想:

  1. 忽略来自在 SQL Server 方面有丰富经验的非常聪明的人的所有警告;
  2. 假设因为在这种情况下您没有遇到日志增长并且在这种情况下修复碎片很快并且不会导致任何进一步增长,情况总是如此;和,
  3. 不确认这个增长/收缩/增长/收缩周期对查询时间有任何影响;

前进。既然你说你只会在极少数情况下这样做,我不确定你在这里寻找什么答案。你想要一个大大的赞,你可以忽略你读过的一切并掷骰子吗?

我至少建议一件事:如果您有 10GB 的数据,就会在 Express 中达到 10GB 的限制。您可以通过删除数据文件中的数据(或将数据分散到多个数据库中)来避免这种情况。如果您释放数据文件中的一堆空间,该空间被重用(如果你删除了一个表,这将是自动的;如果你删除了行或更改了列结构,你将需要重建——这至少也会临时占用一些空间)。因此,如果您释放文件中的 5GB 数据,仅仅因为文件是 9GB 并不意味着如果您添加 2GB,它会尝试变成 11GB - 它会重复使用文件中的空间,直到找不到更多空间。将文件缩小到 4GB,然后强制它增长以容纳新数据将是一个昂贵得多的操作。这就像洗一条已经干净的毛巾,你将用它来擦掉一团糟......

  • @Csaba然后请简化并集中您的问题。我们是否需要序言,40 个指向我们大多数人已经非常熟悉的文章的链接等等。此外,如果 Express 是订阅者并且您的发布者超过 10GB,那么是的,您就被卡住了。取消订阅并修复源,或将订阅者移动到 SQL Server 的真实版本而不受限制。 (5认同)
  • @CsabaToth 我怀疑你没有抓住重点。当您达到 10GB 的数据(不是 10GB 的文件)时,您会卡住。一旦你有 10GB 的数据(不是文件),收缩将不起作用。 (4认同)
  • 为了投入我的 2 美分,我偶尔会缩小一个数据文件,但只有当大量一次性数据被转储到其中然后随后删除导致大量可用空间时。我同意将可用空间留在那里不会导致任何直接问题(驱动器空间除外);但是,如果您需要将相同的数据库备份/恢复到较小的测试/开发环境,您很可能处于完全不可能的位置。如果您永远不会再次使用该空间并愿意支付重建索引的代价,那么我认为没有任何问题。 (2认同)