- Added Jellyfin.Database.Providers.Postgres project with full EF Core migration support for PostgreSQL. - Implemented automatic database creation and privilege assignment on startup. - Generated initial migration and model snapshot for PostgreSQL schema. - Updated build, test, and dependency files to include PostgreSQL provider and Npgsql packages. - Added PowerShell script for generating and testing PostgreSQL migrations. - No changes to application logic outside database provider/migration infrastructure.
7.6 KiB
PostgreSQL Troubleshooting Guide
This guide helps resolve common issues when using PostgreSQL with Jellyfin.
SynchronizationLockException Error
Error Message
System.Threading.SynchronizationLockException: The write lock is being released without being held.
Cause
This error occurs when using Pessimistic locking behavior with PostgreSQL. The issue stems from:
- EF Core interceptors executing on different threads during async operations
ReaderWriterLockSlim.IsWriteLockHeldbeing thread-local, not async-context-aware- Transaction and command interceptors both trying to acquire locks
Solution 1: Use NoLock Behavior (Recommended)
PostgreSQL has built-in MVCC (Multi-Version Concurrency Control) and transaction isolation, making application-level pessimistic locking unnecessary and potentially problematic.
Update your config/database.xml:
<LockingBehavior>NoLock</LockingBehavior>
Complete PostgreSQL Configuration:
<?xml version="1.0" encoding="utf-8"?>
<DatabaseConfigurationOptions>
<DatabaseType>Jellyfin-PostgreSQL</DatabaseType>
<LockingBehavior>NoLock</LockingBehavior>
<CustomProviderOptions>
<Options>
<CustomDatabaseOption>
<Key>host</Key>
<Value>localhost</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>database</Key>
<Value>jellyfin</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>username</Key>
<Value>jellyfin</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>password</Key>
<Value>your_password</Value>
</CustomDatabaseOption>
</Options>
</CustomProviderOptions>
</DatabaseConfigurationOptions>
Solution 2: Fixed Pessimistic Locking (If Needed)
The pessimistic locking implementation has been updated to use AsyncLocal<int> for tracking lock depth across async operations. However, this is not recommended for PostgreSQL as it adds unnecessary overhead.
If you must use pessimistic locking:
- Ensure you have the latest code with the
AsyncLocalfix - Use with caution as it may impact performance
- Monitor for deadlocks in application logs
Connection Issues
Error: "Could not connect to server"
Checks:
-
Verify PostgreSQL is running:
# Linux/macOS systemctl status postgresql # Windows (PowerShell) Get-Service -Name postgresql* -
Test connection manually:
psql -h localhost -U jellyfin -d jellyfin -
Check
pg_hba.confauthentication settings:# Allow local connections host jellyfin jellyfin 127.0.0.1/32 md5 host jellyfin jellyfin ::1/128 md5 -
Restart PostgreSQL after changing configuration:
# Linux/macOS sudo systemctl restart postgresql # Windows Restart-Service postgresql*
Error: "Password authentication failed"
-
Reset the password:
ALTER USER jellyfin WITH PASSWORD 'new_secure_password'; -
Update
database.xmlwith the new password -
Ensure password doesn't contain XML special characters (
<,>,&,',"). If it does, use XML encoding:<→<>→>&→&'→'"→"
Migration Issues
Error: "Database migration failed"
-
Check PostgreSQL version:
psql --versionMinimum required: PostgreSQL 12
-
Verify database exists and is accessible:
psql -h localhost -U jellyfin -d jellyfin -c "SELECT version();" -
Check database user permissions:
-- Connect as postgres superuser GRANT ALL PRIVILEGES ON DATABASE jellyfin TO jellyfin; GRANT ALL PRIVILEGES ON SCHEMA public TO jellyfin; -
Enable detailed logging:
<CustomDatabaseOption> <Key>EnableSensitiveDataLogging</Key> <Value>True</Value> </CustomDatabaseOption>
Performance Issues
Slow Queries
-
Enable Connection Pooling (should be default):
<CustomDatabaseOption> <Key>pooling</Key> <Value>True</Value> </CustomDatabaseOption> -
Increase Command Timeout for large libraries:
<CustomDatabaseOption> <Key>command-timeout</Key> <Value>60</Value> </CustomDatabaseOption> -
Optimize PostgreSQL configuration in
postgresql.conf:shared_buffers = 256MB # 25% of RAM for dedicated server effective_cache_size = 1GB # 50-75% of RAM maintenance_work_mem = 64MB checkpoint_completion_target = 0.9 wal_buffers = 16MB default_statistics_target = 100 random_page_cost = 1.1 # For SSD storage effective_io_concurrency = 200 # For SSD storage work_mem = 4MB -
Create Indexes for common queries (EF Core migrations should handle this, but verify):
-- Check existing indexes SELECT * FROM pg_indexes WHERE schemaname = 'public';
High Memory Usage
PostgreSQL connection pooling maintains connections. To reduce:
<CustomDatabaseOption>
<Key>pooling</Key>
<Value>False</Value>
</CustomDatabaseOption>
⚠️ Warning: Disabling pooling will impact performance.
Debugging
Enable Detailed SQL Logging
Add to config/database.xml:
<CustomDatabaseOption>
<Key>EnableSensitiveDataLogging</Key>
<Value>True</Value>
</CustomDatabaseOption>
⚠️ Security Warning: This logs SQL queries including parameter values. Only use for debugging and disable in production.
Check Jellyfin Logs
Logs are located at:
- Linux:
/var/log/jellyfin/ - Windows:
%PROGRAMDATA%\Jellyfin\Server\log\ - Docker:
/config/log/
Look for lines containing:
PostgreSQL connection:The database locking mode has been set to:- Database errors in the startup sequence
Monitor PostgreSQL Logs
Enable query logging in postgresql.conf:
log_statement = 'all' # Log all queries (very verbose)
log_min_duration_statement = 1000 # Log queries taking > 1 second
Then check PostgreSQL logs:
- Linux:
/var/log/postgresql/ - Windows:
%PROGRAMDATA%\PostgreSQL\<version>\data\log\
Common Configuration Mistakes
1. Wrong Locking Behavior
❌ Don't use:
<LockingBehavior>Pessimistic</LockingBehavior>
✅ Use instead:
<LockingBehavior>NoLock</LockingBehavior>
2. Missing CustomProviderOptions
PostgreSQL requires CustomProviderOptions even though it's now a built-in provider (for backward compatibility).
3. Incorrect Port Format
❌ Wrong:
<Value>postgresql://localhost:5432</Value>
✅ Correct:
<CustomDatabaseOption>
<Key>host</Key>
<Value>localhost</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>port</Key>
<Value>5432</Value>
</CustomDatabaseOption>
Recovery Steps
If Jellyfin won't start due to database issues:
-
Stop Jellyfin
-
Backup Current Configuration
cp config/database.xml config/database.xml.backup -
Switch Back to SQLite (temporary):
<?xml version="1.0" encoding="utf-8"?> <DatabaseConfigurationOptions> <DatabaseType>Jellyfin-SQLite</DatabaseType> <LockingBehavior>NoLock</LockingBehavior> </DatabaseConfigurationOptions> -
Restart Jellyfin and verify it works
-
Fix PostgreSQL configuration and try again
Getting Help
If you're still experiencing issues:
- Enable detailed logging (see Debugging section above)
- Collect logs from both Jellyfin and PostgreSQL
- Note your configuration (without password)
- Check Jellyfin forums/GitHub issues with:
- Error messages
- PostgreSQL version
- Jellyfin version
- Operating system