在生产服务器(Microsoft SQL Server 2014)中,文件MSDBData.mdf
膨胀到超过 450 GB,几乎占用了服务器中的所有空间(仅剩下 38 GB)。
首先,我在MSDB
网络共享上创建了一个备份(通过SSMS -> 活动 -> 备份)。然后我尝试减小文件的大小(通过 SSMS -> 活动 -> 收缩 -> 文件),但是收缩停止并且没有释放磁盘空间。缩小的对话窗口从几个小时开始就被冻结了。
在 SSMS 的活动监控中,在监控收缩的过程中似乎处于SUSPENDED
状态。
在事件查看器中有几个事件
IE
(source MSSQLSERVER, eventid 847) beginning with
1. Time-out occurred while waiting for latch: class 'FGCB_ADD_REMOVE'
2. Time-out occurred while waiting for latch: class 'FCB'
问题:关闭SSMS的对话窗口以停止MSDB的收缩是否安全,以便进行进一步调查?
是的,取消该操作是安全的(但您需要耐心等待它完成回滚 - 不要惊慌并停止 SQL Server 服务或重新启动服务器;所有要做的就是重新开始回滚)。
在您等待的同时,让我们解决您的根本问题。
在您手动增加大小以准备更多数据(或者只是在其他人占用空间之前获得空间)的场景之外,数据文件的大小会增加,因为您将数据添加到文件中,并且它还不够大存储该数据。告诉 SQL Server 缩小必须增长以容纳更多数据的文件不太可能完成任何事情,除非您首先删除一些导致文件增长的数据。
这可能来自流氓备份作业(可能是第 3 方),它每秒都在运行并填充备份历史记录表。或者一个作业运行异常,它正在生成作业历史记录并用错误填充该表。或者是一个无限循环,用垃圾邮件填充数据库邮件表。或其他许多东西,特别是如果您将自己的流程的用户表放入
msdb
.要找出占用空间的内容,您可以使用类似这样的查询和类似这样的查询(存在许多其他查询)。可能是由于碎片,或大量 LOB 数据,或非常糟糕的填充因子,或过大但填充不足的固定宽度列,或只是行数过多,表很大。但是你必须先找到它并把它清理干净,然后收缩才有希望完成任何事情。
删除您不再需要的数据(并采取任何必要的步骤来确保所做的任何过程都不会再次发生)。使用适当的填充因子重建索引,并设置某种维护例程(如Ola 的脚本
msdb
)来管理索引,并可能对数据库(或所有数据库)的太多文件增长事件发出警报,因此您可以捕捉到这一点问题较早。您可以查看最近发生的所有文件增长事件,例如,使用默认跟踪。然后,使用
DBCC SHRINKFILE
(不是 SSMS 中的一些 UI hinkiness,或者DBCC SHRINKDATABASE
,它也会尝试缩小日志,并且会尝试一次缩小所有内容),一次一点点,以降低文件大小。如果文件当前为 450 GB,并且您释放了 300 GB(您可以使用sp_spaceused
查看上述结果),我会得到一个 200 GB 的文件,比方说(为未来增长留出空间),首先缩小到425 GB,然后是 400 GB,然后是 375 GB,依此类推……您可能需要以较小的块来执行此操作,例如从 2 GB 或 5 GB 开始,具体取决于底层磁盘子系统的功能。