Optimize PostgreSQL dead tuple handling for media scans

Introduce bulk operation extensions and transaction helpers for efficient, batched EF Core operations. Refactor MediaStreamInfo schema by splitting audio/video details into dedicated tables, reducing table bloat and improving update performance. Add migration for data movement and schema changes. Update EF Core models and context for new structure. Enhance PostgreSQL provider configuration and add comprehensive documentation and monitoring guides. Includes minor middleware and code cleanups.
This commit is contained in:
2026-04-30 15:52:37 -04:00
parent 6d5282208b
commit 57d6342524
20 changed files with 1995 additions and 339 deletions
@@ -146,6 +146,16 @@ public class JellyfinDbContext(DbContextOptions<JellyfinDbContext> options, ILog
/// </summary>
public DbSet<MediaStreamInfo> MediaStreamInfos => this.Set<MediaStreamInfo>();
/// <summary>
/// Gets the <see cref="DbSet{TEntity}"/> containing audio-specific stream details.
/// </summary>
public DbSet<AudioStreamDetails> AudioStreamDetails => this.Set<AudioStreamDetails>();
/// <summary>
/// Gets the <see cref="DbSet{TEntity}"/> containing video-specific stream details.
/// </summary>
public DbSet<VideoStreamDetails> VideoStreamDetails => this.Set<VideoStreamDetails>();
/// <summary>
/// Gets the <see cref="DbSet{TEntity}"/>.
/// </summary>
@@ -353,6 +363,28 @@ public class JellyfinDbContext(DbContextOptions<JellyfinDbContext> options, ILog
}
}
/// <summary>
/// Gets the recommended batch size for bulk operations based on the number of items to process.
/// Smaller batches during library scans reduce dead tuple generation in PostgreSQL.
/// </summary>
/// <param name="entityCount">The total number of entities being processed.</param>
/// <returns>The recommended batch size for optimal performance.</returns>
public int GetBatchSize(int entityCount)
{
// Smaller batches during media scans = fewer dead tuples
// < 100 items: batch 10
// 100-1000: batch 50
// 1000-10000: batch 100
// > 10000: batch 200
return entityCount switch
{
< 100 => 10,
< 1000 => 50,
< 10000 => 100,
_ => 200
};
}
/// <inheritdoc />
protected override void OnModelCreating(ModelBuilder modelBuilder)
{