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
This commit is contained in:
@@ -1,126 +0,0 @@
|
||||
# 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)
|
||||
```powershell
|
||||
# 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
|
||||
```powershell
|
||||
# Run the full script with checks and verification
|
||||
.\scripts\Apply-SupplementaryIndexes.ps1
|
||||
```
|
||||
|
||||
### Option 3: Manual Step-by-Step
|
||||
|
||||
1. **Connect to database**:
|
||||
```powershell
|
||||
psql -U jellyfin -d jellyfin_testsdata
|
||||
```
|
||||
|
||||
2. **Check current indexes**:
|
||||
```sql
|
||||
SELECT indexname
|
||||
FROM pg_indexes
|
||||
WHERE schemaname = 'library'
|
||||
AND indexname LIKE 'idx_baseitems_%'
|
||||
ORDER BY indexname;
|
||||
```
|
||||
|
||||
3. **Apply supplementary indexes**:
|
||||
```sql
|
||||
\i sql/schema_init/10_create_supplementary_indexes.sql
|
||||
```
|
||||
|
||||
4. **Verify creation**:
|
||||
```sql
|
||||
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:
|
||||
```powershell
|
||||
# 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:
|
||||
```powershell
|
||||
# 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:
|
||||
```powershell
|
||||
# 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:
|
||||
```sql
|
||||
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;
|
||||
```
|
||||
Reference in New Issue
Block a user