5565dc3e05
- 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
80 lines
2.9 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|