【问题标题】:Why my log file need 3 times the size of physical table in sql server为什么我的日志文件需要 sql server 中物理表大小的 3 倍
【发布时间】:2015-05-26 16:29:27
【问题描述】:

我有一个大约600 million records 的表格,表格大小大约为45 GB。我刚刚触发了一个查询以向其添加另一个 bigint 列,即它应该需要大约 4GB 来存储,即

4GB = 600 Million * 8bytes

此表上没有索引。那么为什么这个操作会占用超过 150GB 的日志文件空间。

这是我用来学习不同操作的影响的垃圾数据。

我正在寻找此问题的原因和解决方案。

【问题讨论】:

  • 执行此操作之前的日志有多大。我的猜测是您没有在简单的恢复中运行,并且从未备份/截断日志。在这种情况下,它们将无限增长。
  • 是的,我从未备份过我的数据库。在触发 alter statement 之前,我使用 DBCC SHRINKFILE 缩小到 100 MB,因为空间不足。我应该截断日志而不是缩小日志吗?我的数据库在full recovery model 下运行。

标签: sql-server database database-administration


【解决方案1】:

添加列时,必须更改包含该表中数据的每个页面,并且必须记录每个更改,以便在需要时可以回滚。

https://dba.stackexchange.com/questions/29522/why-does-alter-column-to-not-null-cause-massive-log-file-growth

另外https://social.msdn.microsoft.com/Forums/sqlserver/en-US/6d7aacf6-ff41-4f59-8d4a-bd0909568626/excessive-log-growth-for-alter-column-and-insert-into 并阅读 Lekss 的回答。

【讨论】:

    【解决方案2】:

    您可以考虑使用BULK LOGGED recovery mode 进行此类更改...在更改之前将其打开,然后再返回常规日志记录。在低使用时间或(最好)计划的停机时间进行更改。

    此外,如果您处于 FULL RECOVERY 模式(与 SIMPLE RECOVERY 模式相反),事务日志只会在事务日志备份后清理。完整备份不允许清理事务日志,在这种情况下显式收缩或截断日志不会有帮助。您希望将事务日志备份设置为尽可能频繁地进行 I/O 性能允许,这可能是 a lot more frequently than you think。 SIMPLE RECOVERY 模式避免了这个问题(完全备份确实可以解决所有问题),但您无法进行时间点恢复。

    【讨论】:

    • OP 说数据库从未备份过。在这种特殊情况下,恢复模型无关紧要,它总是表现得像在简单模型中一样。否则不可能缩小日志文件。尽管如此,由于添加列在事务中运行,因此整个操作都已完全记录,因此即使在简单模型中,您也可以获得相当大的日志文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多