如何清理 Hangfire SQL 数据库,保持实际作业运行

问题描述 投票:0回答:1

我使用hangfire已经一年多了,使用hangfire控制台,有些表似乎有来自过期作业的旧信息

我创建了一些脚本来清理 Set 表,但这似乎不对,我的意思是,有数百万条记录

declare @total int = 0
declare @count int = 1

while(@count>0)
begin
delete from [HangFire].[Set] where [key] in (
SELECT top 10000 [key]
FROM [HangFire].[Set]
left join hangfire.job on job.Id = SUBSTRING([Key], 19, LEN([Key]) - 19) 

WHERE [Key] LIKE 'console:%'
and job.id is null

)
set @count = @@ROWCOUNT
set @total = @total + @count
print @total
end

Hash 表也有数百万条记录。

我是否错过了 Hangfire 上的一些配置,以便在作业成功后删除所有这些记录?

这是我的数据库的大小,大约 2GB 用于 3k 个作业

c# hangfire hangfire-sql hangfire-console
1个回答
0
投票

截至 2023 年 4 月下旬,Hangfire 现在公开了一个名为

SqlServerStorageOptions
的新
InactiveStateExpirationTimeout
选项。这是一个
TimeSpan
,用于查找和删除
State
表中的旧条目。

GitHub 源代码

查询如下所示:

$@"
set deadlock_priority low;
set transaction isolation level read committed;
set xact_abort on;
set lock_timeout 1000;

;with cte as (
    select s.[JobId], s.[Id]
    from [{schemaName}].[State] s with (forceseek)
    where s.[CreatedAt] < dateadd(minute, @expireMin, @now)
    and exists (
        select * from [{schemaName}].[Job] j with (forceseek)
        where j.[Id] = s.[JobId] and j.[StateId] != s.[Id]))
delete top(@count) from cte option (maxdop 1);";

其中

@expireMin
定义为
(long)_stateExpirationTimeout.Negate().TotalMinutes
_stateExpirationTimeout
InactiveStateExpirationTimeout

设置

您可以在配置 .NET Core 应用程序期间设置此选项,如下所示:

services.AddHangfire(configuration => configuration
    .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
    .UseSimpleAssemblyNameTypeSerializer()
    .UseRecommendedSerializerSettings()
    .UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection", new SqlServerStorageOptions
{
    InactiveStateExpirationTimeout = TimeSpan.FromDays(1)
    // ... other configuration options
}))
© www.soinside.com 2019 - 2024. All rights reserved.