# 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.IsWriteLockHeld` being 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`:**
```xml
NoLock
```
**Complete PostgreSQL Configuration:**
```xml
Jellyfin-PostgreSQL
NoLock
host
localhost
database
jellyfin
username
jellyfin
password
your_password
```
### Solution 2: Fixed Pessimistic Locking (If Needed)
The pessimistic locking implementation has been updated to use `AsyncLocal` 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:
1. Ensure you have the latest code with the `AsyncLocal` fix
2. Use with caution as it may impact performance
3. Monitor for deadlocks in application logs
## Connection Issues
### Error: "Could not connect to server"
**Checks:**
1. Verify PostgreSQL is running:
```bash
# Linux/macOS
systemctl status postgresql
# Windows (PowerShell)
Get-Service -Name postgresql*
```
2. Test connection manually:
```bash
psql -h localhost -U jellyfin -d jellyfin
```
3. Check `pg_hba.conf` authentication settings:
```
# Allow local connections
host jellyfin jellyfin 127.0.0.1/32 md5
host jellyfin jellyfin ::1/128 md5
```
4. Restart PostgreSQL after changing configuration:
```bash
# Linux/macOS
sudo systemctl restart postgresql
# Windows
Restart-Service postgresql*
```
### Error: "Password authentication failed"
1. Reset the password:
```sql
ALTER USER jellyfin WITH PASSWORD 'new_secure_password';
```
2. Update `database.xml` with the new password
3. Ensure password doesn't contain XML special characters (`<`, `>`, `&`, `'`, `"`). If it does, use XML encoding:
- `<` → `<`
- `>` → `>`
- `&` → `&`
- `'` → `'`
- `"` → `"`
## Migration Issues
### Error: "Database migration failed"
1. Check PostgreSQL version:
```bash
psql --version
```
Minimum required: PostgreSQL 12
2. Verify database exists and is accessible:
```bash
psql -h localhost -U jellyfin -d jellyfin -c "SELECT version();"
```
3. Check database user permissions:
```sql
-- Connect as postgres superuser
GRANT ALL PRIVILEGES ON DATABASE jellyfin TO jellyfin;
GRANT ALL PRIVILEGES ON SCHEMA public TO jellyfin;
```
4. Enable detailed logging:
```xml
EnableSensitiveDataLogging
True
```
## Performance Issues
### Slow Queries
1. **Enable Connection Pooling** (should be default):
```xml
pooling
True
```
2. **Increase Command Timeout** for large libraries:
```xml
command-timeout
60
```
3. **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
```
4. **Create Indexes** for common queries (EF Core migrations should handle this, but verify):
```sql
-- Check existing indexes
SELECT * FROM pg_indexes WHERE schemaname = 'public';
```
### High Memory Usage
PostgreSQL connection pooling maintains connections. To reduce:
```xml
pooling
False
```
⚠️ **Warning**: Disabling pooling will impact performance.
## Debugging
### Enable Detailed SQL Logging
Add to `config/database.xml`:
```xml
EnableSensitiveDataLogging
True
```
⚠️ **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\\data\log\`
## Common Configuration Mistakes
### 1. Wrong Locking Behavior
❌ **Don't use:**
```xml
Pessimistic
```
✅ **Use instead:**
```xml
NoLock
```
### 2. Missing CustomProviderOptions
PostgreSQL requires `CustomProviderOptions` even though it's now a built-in provider (for backward compatibility).
### 3. Incorrect Port Format
❌ **Wrong:**
```xml
postgresql://localhost:5432
```
✅ **Correct:**
```xml
host
localhost
port
5432
```
## Recovery Steps
If Jellyfin won't start due to database issues:
1. **Stop Jellyfin**
2. **Backup Current Configuration**
```bash
cp config/database.xml config/database.xml.backup
```
3. **Switch Back to SQLite** (temporary):
```xml
Jellyfin-SQLite
NoLock
```
4. **Restart Jellyfin** and verify it works
5. **Fix PostgreSQL configuration** and try again
## Getting Help
If you're still experiencing issues:
1. Enable detailed logging (see Debugging section above)
2. Collect logs from both Jellyfin and PostgreSQL
3. Note your configuration (without password)
4. Check Jellyfin forums/GitHub issues with:
- Error messages
- PostgreSQL version
- Jellyfin version
- Operating system