Files
pgsql-jellyfin/Jellyfin.Server.Implementations/Database/SupplementaryIndexChecker.cs
T
wjones 5565dc3e05 Add automated PostgreSQL performance index management
- Add scripts and SQL for base and supplementary indexes (total 23)
- Integrate index checks and auto-creation into Jellyfin startup
- Update csproj to include SQL files in build/publish output
- Add diagnostics, publish/copy scripts, and troubleshooting docs
- Provide detailed guides for migration, verification, and merging
- Ensures robust, automated, and well-documented index setup
2026-02-28 15:13:04 -05:00

80 lines
2.9 KiB
C#

// <copyright file="SupplementaryIndexChecker.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace Jellyfin.Server.Implementations.Database;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Npgsql;
/// <summary>
/// Ensures supplementary performance indexes exist on database startup.
/// </summary>
public class SupplementaryIndexChecker
{
private readonly ILogger<SupplementaryIndexChecker> _logger;
private readonly DbContext _context;
/// <summary>
/// Initializes a new instance of the <see cref="SupplementaryIndexChecker"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="context">The database context.</param>
public SupplementaryIndexChecker(ILogger<SupplementaryIndexChecker> logger, DbContext context)
{
_logger = logger;
_context = context;
}
/// <summary>
/// Checks if supplementary indexes exist and logs warnings if they don't.
/// </summary>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>True if all indexes exist, false otherwise.</returns>
public async Task<bool> CheckSupplementaryIndexesAsync(CancellationToken cancellationToken = default)
{
try
{
var connection = _context.Database.GetDbConnection();
await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
var checkQuery = @"
SELECT COUNT(*)
FROM pg_indexes
WHERE indexname IN (
'idx_baseitems_type_isvirtualitem_topparentid',
'idx_baseitems_topparentid_isfolder',
'idx_baseitems_datecreated_filtered',
'idx_itemvaluesmap_itemvalueid_itemid',
'idx_activitylogs_userid_datecreated'
)";
await using var command = connection.CreateCommand();
command.CommandText = checkQuery;
var result = await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false);
var indexCount = Convert.ToInt32(result);
if (indexCount < 5)
{
_logger.LogWarning(
"Only {IndexCount}/5 supplementary performance indexes found. " +
"Run 'sql/schema_init/10_create_supplementary_indexes.sql' to add missing indexes for better performance.",
indexCount);
return false;
}
_logger.LogInformation("All supplementary performance indexes are present ({IndexCount}/5).", indexCount);
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to check supplementary indexes");
return false;
}
}
}