2012-12-26 47 views
3

我在SQL Server 2008 R2中有一个数据库,其中有数百万个文件存储为varbinary blob。我上周设置了一个过程来执行以下操作:SQL Server日志文件在简单恢复模式下填充

  1. 使用一些实体框架代码来获取具有blob的行(即实体)。
  2. 将blob流复制到对象存储。
  3. 使用商店中的新对象ID更新数据库中的实体。

我有30个线程经常这样做,这个过程仍然需要几天。几天前,数据库日志文件已填满,我相信它必须由此过程引起。我确定时间点备份对于此数据库并不重要,并且将数据库设置为使用简单恢复模式。然后昨天我再次从我的过程中得到错误,说日志文件填满了!这在简单模式下如何实现?!任何想法我能做些什么来阻止这种情况的发生?当我监视日志文件时,SQL Server会让它达到7%的饱和度,然后将其截断为零,所以我感到非常困惑。看起来好像当完整备份开始时日志文件开始增长未被选中...

回答

3

即使在简单恢复模式下,SQL Server也会填充日志文件以保持ACID合规性并允许回滚(或“转发“在某些灾难恢复情况下)。因此,您需要有足够的空间来至少处理它可能一次收到的交易,否则它将自动增长或出现错误。

现在作为一个实际问题,您有几个选项。最简单的就是给它足够的空间来处理交易。另一种方法是将其分解为更少的事务,因为在简单恢复中,一旦事务完全提交并最终完成,它将允许重用该空间。

为清晰起见并对意见进行编辑:即使未调用明确的操作,SQL Server也会在隐式事务中放置几乎所有的操作(这里有一些例外,但这些操作并不重要)。所以,如果你说执行一个插入一百万行的命令,它将为该插入提供一个隐式事务,并且即使在简单恢复模式下,所有这百万行都会影响事务日志,直到事务完全提交并完成。如果你想让它更快地释放空间,重写你的代码,以便插入一百万行而不是一条语句,而你有十条语句插入十万条。

从您的问题中可以看出,在完整备份过程中,只有只有增长,但是备份过程确实会影响其在发生日志时释放空间的能力。这是因为完整备份还包含日志文件中的数据,因此服务器需要确保在备份过程中信息可用。在In Recovery有相关的讨论。

我通常会极度不愿推迟计划的备份,但它可能有助于这种特殊情况。这听起来像是把你的交易分成小块可能最终成为一种方式。

+0

我根本没有使用事务,至少没有明确地说,我没有剩余的空间来分配。我不认为你的回答告诉我为什么它只在完全备份期间增长,是吗?我的猜测是,这与那里没有任何活动的休息点有关。 – influent

+0

@influent我编辑了答案来澄清。 SQL Server不*需要一个没有活动的休息点,但它确实需要在备份开始之前启动的事务完成。 – TimothyAWiseman

+0

谢谢。每条语句只更新一行,没有批次。我明白现在发生了什么(http://technet.microsoft.com/en-us/library/ms345414.aspx,ACTIVE_BACKUP_OR_RESTORE),但我不知道如何解决它,因为我没有任何剩余空间。我可能必须在另一个驱动器上添加第二个日志文件,以便完整备份可以在日志文件没有填满的情况下完成。 – influent

0

它好像日志文件开始全面 备份开始时增长未选中...

所以,当你正在做一个完整的备份只生长?这是有道理的,因为完整备份包含所有数据页面以及在备份过程中生成的日志记录范围。

所以,当备份运行时,日志可能无法被截断。请注意,这是(受过教育的)我的猜测。

您可以通过查看sys.databases.log_reuse_wait_desc值来确认这一点。

+1

我确认了,谢谢。 – influent

相关问题