【问题标题】:Huge transaction log with SQL Server database in simple recovery modeSQL Server 数据库在简单恢复模式下的巨大事务日志
【发布时间】:2009-07-28 18:28:27
【问题描述】:

我有一个使用简单恢复模式的相当大的 SQL Server 数据库。我们真的不需要第二次恢复,所以我希望我们保持这种模式。

由于某种原因,此数据库的事务日志非常庞大 (410 GB),其中 99% 的空间未分配。

我尝试使用 ( DBCC SHRINKFILE (MyDatabase_log, 20000) ) 缩小文件,但它似乎不起作用。

任何人对为什么简单恢复模式的数据库会有这么大的文件有任何提示吗?我真的很想把它缩小。

【问题讨论】:

  • 上次我检查时,默认的收缩单位是 GB。所以你声明的可能是20000 GB,这不会有任何影响:)

标签: sql-server


【解决方案1】:

这意味着您曾经有一个事务持续了很长时间,以至于它迫使日志增长 410GB。如果存在活动事务,则无法重用日志,因为无法擦除回滚信息。例如,如果有人打开 SSMS 查询、启动事务、更新记录然后去度假。事务将处于活动状态并强制日志增长,直到最终提交或回滚。当事务最终结束时,使用的空间最终可以被回收,留下一个巨大的空日志文件。

另一种情况是,如果您在单个事务中更新了大约 200GB 的数据。日志将存储更改前后的图像,因此占用了两倍的空间,并且无法重复使用,因为都是一个事务。

更新

我忽略了复制,它也是可以防止日志截断的一个因素。镜像也是如此,一种分布式事务(从技术上讲,这与“活动事务”相同,但 DTC 的含义使它成为一个独特的案例)。完整列表和说明在Factors That Can Delay Log Truncation

【讨论】:

  • 如果在回滚/事务中,它不会显示为未分配空间,对吗?
  • 谢谢!这听起来很有可能。如果日志处于这种锁定状态,您知道如何删除日志吗?
  • 如果它显示为未分配,则该空间必须已被 SIMPLE 恢复模式收回。所讨论数据库的 sys.databases 的 log_reuse_wait_desc 列是否显示 NOTHING
  • @Eric (OP) 来自对 no_one 的回复,很明显您有来自数据库的复制。复制是其中的另一个日志收缩/重用限制因素。您需要所有订阅者都赶上来,服务器会跟踪谁收到了复制中的内容。如果订阅者落后,则会导致日志增长,与活动事务相同。
  • 是的。关闭复制现在允许我使用 NOTRUNCATE 缩小日志。谢谢埃里克和莱姆斯!
【解决方案2】:

您在dbcc shrinkfile 中缺少一个参数:

dbcc shrinkfile (MyDatabase_log, 20000, TRUNCATEONLY)

NOTRUNCATE 是默认值,它将已分配的块移动到未分配空间的开头。 TRUNCATEONLY 删除未分配的空间。因此,如果您执行NOTRUNCATE 后跟TRUNCATEONLY,您会得到一个精简的日志。

【讨论】:

  • 我确实尝试过。它没有改变任何东西。当空间用完时,我确实添加了第二个日志文件以使 batabase 重新联机。也许这是其中的一部分?
  • @Eric(好名字,顺便说一句):那么请确保您正在缩小正确的日志。如果您有两个日志文件,则需要分别收缩这两个文件。检查数据库属性的“文件”部分以了解它们的名称。我认为默认是MyDatabase_log_1,但我想不通。
  • 我阅读的文档说默认单位是 GB,而不是 MB,这可能是这不起作用的根本原因。这可能因 SQL Server 版本而异 - 我不确定。
【解决方案3】:

如果您只有一个 mdf 文件和一个日志文件,也许最简单的方法是分离数据库、重命名日志并重新附加数据库。 SQL Server 将创建一个新的日志文件。之后,您的巨大日志文件可以安全地删除。

如果您有多个数据文件,这将不起作用。

【讨论】:

  • 谢谢。我确实尝试过,但它不会让我分离,因为数据库充当复制发布者。
  • 这很好用,我不能让世界上所有的 DBCC SHRINKFILE 都缩水不动。无论如何,这只是一个测试数据库而不是生产数据库,所以我尝试了这个。效果很好,只需要删除“重新附加”.ldf 文件部分,因为它显然不存在。谢谢!
【解决方案4】:

复制发布者?这可能是交易日志庞大的原因吗?

【讨论】:

    【解决方案5】:

    正如其他回复中所说,Active TransactionsReplications 是导致此问题的典型原因。
    另一个不太明显的是Change Data Capture (CDC)。

    我最近遇到了类似的问题,释放日志的过程如下:

    • 禁用 CDC:EXEC sys.sp_cdc_disable_db
    • 在相关数据库中的任意表上创建发布
    • 删除此/所有出版物。 EXEC sp_removedbreplication 'my_db' 是一种方便的方式。
    • 根据需要收缩日志

    我不确定为什么有必要创建/删除此虚拟/从未使用出版物,但确实如此。试探性地,数据库可能有未正确处理的以前的发布(据说从以前的备份恢复的数据库经常发生这种情况)。

    另一个有用的诊断习惯是检查 sys.databases 中的 log_reuse_wait_desc 是否有问题的数据库。在我完成上述过程之前,该字段为REPLICATION

    SELECT log_reuse_wait_desc, * FROM sys.databases where name = 'my_db'
    

    【讨论】:

      【解决方案6】:

      我在本地开发数据库上遇到了类似的问题,并且只能在数据库上运行 CHECKPOINT 几次后使其缩小,不确定是什么让它处于锁定状态。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-29
        • 1970-01-01
        • 2019-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多