我正在使用 500 GB 的 SQL Server 数据库。在删除大量 (50%) 数据后,我需要减小数据库数据文件的大小。
我尝试重新建立索引,数据库已经碎片化了,这很好。但是数据库大小并没有减少。
我不准备使用收缩数据库。我已经尝试过压缩和 DBCC UpdateUsage 但没有增加空间。请告诉我任何其他减少数据库大小的方法。
我们的客户不允许我们将数据库脱机。缩小数据库可能需要 5 小时,然后重新索引将需要 3 小时,因此总共需要 8 小时的停机时间。我正在寻找一种无需停机的解决方案。
步骤 0) 收缩免责声明
我什至不想说。我会让 Brent Ozar 告诉你停止收缩你的数据库文件。严重地。现在。
在您的评论中,您提到您删除了数据库中 50% 的数据,因此您很可能有一个很好的一次性数据库收缩用例。(假设删除的数据不会回来。)
我什至不打算触及缩小的原木。我们只是在谈论数据文件。
步骤 1) 查看文件大小
在真正考虑缩小文件之前,先看看文件大小和有多少可用空间。在要收缩其数据文件的数据库中运行此命令:
SELECT
LogicalName = dbf.name
,FileType = dbf.type_desc
,FilegroupName = fg.name
,PhysicalFileLocation = dbf.physical_name
,FileSizeMB = CONVERT(DECIMAL(10,2),dbf.size/128.0)
,UsedSpaceMB = CONVERT(DECIMAL(10,2),dbf.size/128.0
- ((dbf.size/128.0) - CAST(FILEPROPERTY(dbf.name, 'SPACEUSED') AS INT)/128.0))
,FreeSpaceMB = CONVERT(DECIMAL(10,2),dbf.size/128.0
- CAST(FILEPROPERTY(dbf.name, 'SPACEUSED') AS INT)/128.0)
FROM sys.database_files dbf
LEFT JOIN sys.filegroups fg ON dbf.data_space_id = fg.data_space_id
ORDER BY dbf.type DESC, dbf.name;
Run Code Online (Sandbox Code Playgroud)
如果您查看结果中的FreeSpaceMB列,那么这就是您可能能够回收的未使用空间量。如果它很重要,您可能会决定继续并缩小文件。
步骤 2) 考虑副作用
如果缩小数据文件,位于文件“末尾”的任何数据都需要与文件中的其他地方相关联。这些操作会被记录下来,因此您将生成大量事务日志使用情况(除非您的数据库正在SIMPLE恢复中)。确保您的事务日志足够大,并确保您足够频繁地运行事务日志备份。
如果您的数据库正在被镜像,或者在一个可用性组中,或者正在传送日志,您可能会发现您的辅助服务器在此操作期间落后。
收缩会产生很多碎片。根据您的工作负载,您可能会在此过程中对性能产生影响。
收缩会产生一堆 IO。如果您已经看到 IO 问题,那么缩小可能会加剧这种情况,并且在此过程中可能会影响性能。
收缩是一个主要的在线过程,其中数据逐页移动到文件的“前端”,以便可以截断文件的末尾。我说的主要是在线,因为此操作可能会导致阻塞——我在 PRIMARY 文件组中特别经常看到这种情况。由于这可能导致阻塞,我从不让它在无人看管的情况下运行,也从不在高峰工作时间运行。
确定你需要收缩。
步骤 3) 收缩文件
当我缩小时,我总是使用DBCC SHRINKFILE( BOL ),从不使用DBCC SHRINKDATABASE。如果我要缩小文件,我希望尽可能多地控制这个过程。
使用上面的输出SELECT,找出您想用于数据库目标大小的内容——您需要在数据文件中保留一些可用空间,否则它会立即变得更大。
现在您可以构建语句来缩小您的数据文件。请记住,这是一个在线过程,但如果您担心影响性能,请在运行时仔细观察 yoru 服务器:
USE [DatabaseName];
DBCC SHRINKFILE(LogicalName, TargetSize);
Run Code Online (Sandbox Code Playgroud)
第 4 步)审查碎片
恭喜,您已成功创建了大量物理碎片。我知道有些商店运行的应用程序碎片不会造成任何问题。如果您是这些商店中的一员,那么您就大功告成了——停止阅读。
如果碎片确实影响了您的性能,那么您已经有定期安排的索引维护工作。缩小数据文件后,运行该定期索引维护作业以解决问题。
如果您没有定期的索引维护工作,那么您需要做一件事:找出最佳选择,以及是否需要考虑。Kendra Little 在这里很好地介绍了该主题。我个人喜欢Ola Hallengren 的 IndexOptimize 程序。
请记住:即使您正在运行标准版,它REORGANIZE是一个在线操作,如果您杀死它,您也不会丢失您的工作——它会在下一次停止的地方继续。
它可以完全在线完成
您可以使用DBCC SHRINKFILE和REORGANIZE完全在线完成此操作。如果收缩导致影响生产的大量碎片,您可以在更小的块中收缩/重组/收缩/重组。这将需要非常非常长的时间。但这是一个权衡……有更快的方法,但这些方法可能涉及不同数量的停机时间。
最简单的解决方案是让数据库半满,并接受您使用的磁盘空间超出您的需要。
| 归档时间: |
|
| 查看次数: |
29420 次 |
| 最近记录: |