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
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user