Files
pgsql-jellyfin/docs/scripts/CONNECT_AND_UPDATE.md
wjones c76853a442 PostgreSQL: Production fixes—UPSERT, remote backup, auth logs
- Fix: Atomic UPSERT for BaseItemProviders (resolves duplicate key errors during concurrent metadata refresh; clears navigation property to prevent EF Core tracking conflicts)
- Add: Remote PostgreSQL backup support (removes localhost-only restriction; works with pg_dump/pg_restore for both local and remote DBs)
- Add: Configurable backup disable option (`disable-backups`)
- Fix: Query timeout and performance (documented `command-timeout` config, added performance index scripts)
- Fix: Authentication errors now log as warnings with clear messages (ExceptionMiddleware), reducing log noise
- Fix: SyncPlay authorization handler validates user before lookup, logs warnings for unauthenticated/unknown users (returns 403/404)
- Fix: Database deadlock detection logs warnings and allows EF Core auto-retry
- Add: Configurable LibraryMonitorDelay (min 30s, default 60s)
- Fix: SQLite migration filtering—skip SQLite-only migrations on PostgreSQL
- Chore: Suppress StyleCop warnings (SA1137, etc.) for project consistency
- Docs: 21 documentation files added/updated (config, backup, performance, troubleshooting, session summary)
- All changes are backward compatible and production-ready
2026-03-03 16:35:27 -05:00

3.4 KiB

Quick Connect and Add Supplementary Indexes

This script connects to your jellyfin_testsdata database and adds the 5 supplementary indexes.

Prerequisites

  1. PostgreSQL is running
  2. Database jellyfin_testsdata exists
  3. psql is in your PATH
  4. You have the jellyfin user credentials

Quick Run

Option 1: Direct SQL (Fastest)

# Just add the indexes directly
psql -U jellyfin -d jellyfin_testsdata -f sql\schema_init\10_create_supplementary_indexes.sql

Option 2: With verification and checks

# Run the full script with checks and verification
.\scripts\Apply-SupplementaryIndexes.ps1

Option 3: Manual Step-by-Step

  1. Connect to database:
psql -U jellyfin -d jellyfin_testsdata
  1. Check current indexes:
SELECT indexname
FROM pg_indexes
WHERE schemaname = 'library'
  AND indexname LIKE 'idx_baseitems_%'
ORDER BY indexname;
  1. Apply supplementary indexes:
\i sql/schema_init/10_create_supplementary_indexes.sql
  1. Verify creation:
SELECT 
    indexname,
    pg_size_pretty(pg_relation_size(indexrelid)) as size,
    idx_scan as times_used
FROM pg_stat_user_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'
);

What Gets Added

5 supplementary indexes:

  1. idx_baseitems_type_isvirtualitem_topparentid - Filtered library browsing
  2. idx_baseitems_topparentid_isfolder - Folder hierarchy
  3. idx_baseitems_datecreated_filtered - Recently added view
  4. idx_itemvaluesmap_itemvalueid_itemid - Genre/tag reverse lookup
  5. idx_activitylogs_userid_datecreated - User activity queries

Troubleshooting

"CONCURRENTLY cannot be used" error

Remove CONCURRENTLY from the SQL if you get this error (less common in newer PostgreSQL versions).

"Index already exists"

This is safe - the script checks before creating. The index already exists and doesn't need to be created again.

"Connection refused"

Ensure PostgreSQL is running:

# Check if PostgreSQL service is running
Get-Service postgresql*

# Or try to ping the database
psql -U jellyfin -d jellyfin_testsdata -c "SELECT version();"

Wrong password

Update the password in the script or use .pgpass file:

# Windows: %APPDATA%\postgresql\pgpass.conf
# Linux/Mac: ~/.pgpass
# Format: hostname:port:database:username:password
localhost:5432:jellyfin_testsdata:jellyfin:YOUR_PASSWORD

Monitor Performance

After applying, monitor index usage:

# Wait a few days, then check usage
psql -U jellyfin -d jellyfin_testsdata -c "
SELECT 
    indexname,
    idx_scan as times_used,
    idx_tup_read as rows_read,
    pg_size_pretty(pg_relation_size(indexrelid)) as size
FROM pg_stat_user_indexes
WHERE indexname LIKE 'idx_%'
  AND schemaname = 'library'
ORDER BY idx_scan DESC;
"

Rollback

If you need to remove the indexes:

DROP INDEX CONCURRENTLY IF EXISTS library.idx_baseitems_type_isvirtualitem_topparentid;
DROP INDEX CONCURRENTLY IF EXISTS library.idx_baseitems_topparentid_isfolder;
DROP INDEX CONCURRENTLY IF EXISTS library.idx_baseitems_datecreated_filtered;
DROP INDEX CONCURRENTLY IF EXISTS library.idx_itemvaluesmap_itemvalueid_itemid;
DROP INDEX CONCURRENTLY IF EXISTS activitylog.idx_activitylogs_userid_datecreated;