【问题标题】:SQL Server log file grew 40GB with Hangfire使用 Hangfire 的 SQL Server 日志文件增长了 40GB
【发布时间】:2016-01-19 09:04:34
【问题描述】:

我使用在 IIS 中运行的 MVC 开发了一个 Hangfire 应用程序,它工作得非常好,直到我看到我的 SQL Server 日志文件的大小,一夜之间增长了 40 GB!

根据我们的 DBA 提供的信息,有一个长时间运行的事务,带有以下 SQL 语句(我有 2 个挂起队列)-

(@queues1 nvarchar(4000),@queues2 nvarchar(4000),@timeout float)
delete top (1) from [HangFire].JobQueue with (readpast, updlock, rowlock)
output DELETED.Id, DELETED.JobId, DELETED.Queue
where (FetchedAt is null or FetchedAt < DATEADD(second, @timeout, GETUTCDATE()))
and Queue in (@queues1,@queues2)

在探索 Hangfire 库时,我发现它用于使作业出队,并执行一项非常简单的任务,不应该花费任何时间。 我找不到任何会导致此错误的东西。事务与using 语句一起正确使用,对象为Disposed,以防出现异常。

正如一些帖子中所建议的,我检查了我的数据库的恢复模式并验证它很简单。

我手动终止了挂起的事务以回收日志文件空间,但几个小时后它又出现了。我一直在观察它。

这种行为的原因可能是什么?以及如何预防?

这个问题似乎是间歇性的,部署在生产环境中的风险可能非常高:(

【问题讨论】:

  • 您是否为SqlServerStorageOptions.QueuePollInterval 属性设置了自定义值?使用什么值?
  • @odinserj:不,我没有改变它。它应该使用默认的 15 秒间隔。
  • 你们总共有多少工人?
  • @odinserj - 我总共有 20 名工人
  • @odinserj - 如果我错了,请纠正我,我观察到事务在作业执行之前一直保持打开状态。因此,对于需要几个小时才能完成的长时间运行的作业,事务是打开的,并且它会不断增加日志大小。如果正确,如何解决。

标签: c# hangfire


【解决方案1】:

从 Hangfire 1.5.0 开始,Hangfire.SqlServer 实现将后台作业的整个处理与事务包装在一起。以前的实现使用不可见超时来提供至少一次处理保证,而不需要事务,以防进程意外关闭。

我已经为队列处理实现了一个新模型,因为对于新用户来说有很多困惑,尤其是那些刚刚安装 Hangfire 并在调试会话中使用它的用户。有很多问题,例如“为什么我的工作仍处于处理状态?”。我考虑过事务日志增长可能存在问题,但我不知道即使使用简单恢复模型也会发生这种情况(请参阅this answer 了解原因)。

看起来应该有一个开关,使用什么队列模型,基于事务(默认)或基于不可见超时。但是这个功能仅在 1.6 中可用,我还不知道任何 ETA。

目前,您可以使用Hangfire.SqlServer.MSMQ 或任何其他非RDBMS 队列实现(请参阅Extensions 页面)。 Hangfire 的单独数据库也可能会有所帮助,尤其是在您的应用程序更改大量数据时。

【讨论】:

  • +1 为您的答案@odinserj。现在我知道关于hangfire的官方信息是什么了。我会在这个问题上做更多的工作,并会尝试找出解决方案。我想到的一件事是应用程序和 hangfire 数据库现在是相同的。可能这就是问题所在。我将尝试通过分离数据库再次进行测试。而且你的工具很棒:)
  • 考虑使用 MSMQ 扩展,这将完全删除长时间运行的事务,并且由于在获取作业时阻塞调用,延迟将最小化。后台作业信息将保留在 SQL Server 中,但在这种情况下,队列将由 MSMQ 驱动。
  • 拥有一个单独的用于hangfire 的数据库在一定程度上解决了这个问题。现在非常顺利。话虽如此,最好使用 msmq 或 redis 等存储以获得最佳性能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
相关资源
最近更新 更多