这里有点让人头疼。
我有一个数据少于 1GB 的数据库,但有一个 40GB 的日志文件。事务日志每天备份,这个数据库上没有很多活动;大约每周一次,它会记录新的工资单信息,然后将这些数据重复用于报告目的。数据库设置为自动收缩。
运行sp_spaceused @updateusage = true
产生以下信息:
database_name database_size unallocated space
PayrollImports 39412.06 MB 105.00 MB
reserved data index_size unused
321728 KB 278640 KB 42816 KB 272 KB
运行DBCC shrinkfile (N'PayrollImports_log', 1 , notruncate)
产生以下结果:
DbId FileId CurrentSize MinimumSize UsedPages EstimatedPages
19 2 4991088 3456 4991088 3456
UsedPages
... the和 the之间的差异EstimatedPages
令人费解,但我继续DBCC shrinkfile (N'PayrollImports_log', 1 , truncateonly)
并得到:
DbId FileId CurrentSize MinimumSize UsedPages EstimatedPages
19 2 4991088 3456 4991088 3456
在这一点上什么都没有改变。日志文件仍然是 40GB。所以我想,也许我有一些公开交易。运行dbcc opentran
应验证:
No active open transactions.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
废话。好吧,也许我的索引是零散的。我将对它们进行碎片整理sp_msForEachTable 'DBCC indexdefrag([PayrollImports], ''?'')'
并尝试再次缩小:
DbId FileId CurrentSize MinimumSize UsedPages EstimatedPages
19 2 4991088 3456 4991088 3456
仍然没有任何改变。好的,我用 重新索引怎么样sp_msForEachTable 'DBCC dbreindex([?])'
?
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
...现在我们得到:
DbId FileId CurrentSize MinimumSize UsedPages EstimatedPages
19 2 4991088 3456 4991088 3456
没变。好吧,怎么样sp_msForEachTable 'ALTER INDEX ALL ON [PayrollImports].[?] REBUILD WITH (FILLFACTOR = 10)'
?
立即,这失败了:
Cannot find the object "(One of my tables)" because it does not exist or you do not have permissions.
嗯?它在那里,好的。我做了一个select top 10 * from (My table)
,它空了。嗯,这根本不对。这是一个应该有超过 200 行的查找表。这可能是数据损坏问题吗?我从我的开发环境中收集数据,重新插入。
但我没有想法。我不能缩小这个东西。我还能尝试什么?为什么我的 UsedPages 比我的 EstimatedPages 高得难以置信?这里发生了什么?
DBCC LOGINFO
在数据库的上下文中检查您的输出。这将向您显示日志文件中所有 VLF 的状态。您的收缩操作不会将日志文件减少到最后一个活动文件(状态=2)之后。由于 VLF 以顺序、循环方式使用,因此您需要运行事务日志备份足够多次,直到您的活动 VLF 位于文件中您想要收缩到的物理点。虽然您说数据库不是很活跃,但每天一次的事务日志备份似乎非常罕见,并且根据针对该数据库运行的事务类型,可能有助于该数据库的持续增长。我建议至少每小时运行一次日志备份。如果您不需要在数据库中进行这种恢复,而只需要恢复到过去 24 小时内的某个时间,我建议您将数据库转换为
SIMPLE
模式并每天进行一次完整备份。Mike Walsh在这里提供了详细的解释。
您的重新索引对实际缩小或允许文件缩小几乎没有作用,实际上可能会阻碍它。这是因为重新索引会在您的日志中创建额外的事务,这些事务将在您运行日志备份之前一直处于活动状态。
此外,一些最佳实践建议:
truncate_only
. 这基本上使您的日志无法用于恢复。此时您最好使用SIMPLE
模式和完整备份。