这是我的场景:我们有一个数据库,我们称它为 Logging,其中包含一个保存来自 Log4Net 的记录(通过 MSMQ)的表。数据库的恢复模式设置为简单:我们不关心事务日志——它们可以翻转。
我们有一个作业,它使用 sp_spaceused 中的数据来确定我们是否达到了某个大小阈值。如果超过阈值,我们将确定需要删除多少行才能将大小降低到该阈值的 x%。(顺便说一句,我正在使用 exec sp_spaceusedMyLogTable
来TRUE
获取行数和它们平均大小的粗略近似值,尽管我不相信这是最好的方法。但这是一个不同的问题。)
然后我尝试通过循环调用基本上执行此操作的 sproc 来分块删除(例如,一次 5000 个):
DELETE TOP (@RowsToDelete) FROM [dbo].[MyLogTable]
直到我删除了需要删除的内容。
问题是:如果我有很多行要删除,事务日志文件就会填满。我可以通过跑步看着它成长
dbcc sqlperf (logspace)
令我困惑的是,当作业失败时,所有已删除的行都会回滚。换句话说,似乎所有块都被(以某种方式)包装在隐式事务中。
我已经尝试明确设置隐式事务关闭,将每个 DELETE 语句包装在 BEGIN 和 COMMIT TRAN 中,但无济于事:要么所有删除的块都成功,要么根本没有。
我知道简单的答案是,使您的日志文件足够大,以处理您曾经删除的尽可能多的记录,但是,为什么这被视为单个事务?
抱歉,如果我错过了一些简单的事情,但是我查看了很多有关日志文件增长、恢复模式等的帖子,但我无法弄清楚这一点。
另一件事:一旦作业失败,日志文件会在一段时间内保持在 95% - 100% 左右,然后再回落。但是,如果我运行
checkpoint
dbcc dropcleanbuffers
它立即回落到大约 5% 的利用率。
TIA。