88dba54087
Introduced backup/restore via external pg_dump/pg_restore tools, configurable in database.xml. Added DatabaseBackupOptions, PostgresBackupService, and example/config docs. Backup features are enabled only for local databases; remote DBs require manual management. Logging and documentation clarify external tool usage, error handling, and security. Updated provider logic and assembly files accordingly.
201 lines
6.2 KiB
Markdown
201 lines
6.2 KiB
Markdown
# PostgreSQL Backup Configuration - Implementation Summary
|
|
|
|
## What Was Created
|
|
|
|
This implementation adds configurable PostgreSQL backup options to Jellyfin that can be configured through the `database.xml` file.
|
|
|
|
### New Files Created:
|
|
|
|
1. **`DatabaseBackupOptions.cs`**
|
|
- Location: `src/Jellyfin.Database/Jellyfin.Database.Implementations/DbConfiguration/`
|
|
- Contains all configurable backup settings
|
|
- Properties: PgDumpPath, PgRestorePath, BackupFormat, CompressionLevel, TimeoutSeconds, etc.
|
|
|
|
2. **`PostgresBackupService.cs`**
|
|
- Location: `src/Jellyfin.Database/Jellyfin.Database.Providers.Postgres/`
|
|
- Service class that performs backup and restore operations
|
|
- Reads configuration from `database.xml`
|
|
- Executes `pg_dump` and `pg_restore` with configured options
|
|
|
|
3. **`database.xml.example`**
|
|
- Location: `src/Jellyfin.Database/Jellyfin.Database.Implementations/DbConfiguration/`
|
|
- Example configuration file showing all available options
|
|
- Can be copied to Jellyfin's config directory
|
|
|
|
4. **`BACKUP_CONFIGURATION.md`**
|
|
- Location: `src/Jellyfin.Database/Jellyfin.Database.Providers.Postgres/`
|
|
- Complete documentation for end users
|
|
- Configuration reference and troubleshooting guide
|
|
|
|
### Modified Files:
|
|
|
|
1. **`DatabaseConfigurationOptions.cs`**
|
|
- Added `BackupOptions` property to hold backup configuration
|
|
|
|
## How It Works
|
|
|
|
### Configuration Flow:
|
|
|
|
```
|
|
database.xml
|
|
↓
|
|
DatabaseConfigurationOptions.BackupOptions
|
|
↓
|
|
PostgresBackupService reads options via IConfigurationManager
|
|
↓
|
|
pg_dump/pg_restore executed with configured parameters
|
|
```
|
|
|
|
### Example database.xml:
|
|
|
|
```xml
|
|
<DatabaseConfigurationOptions>
|
|
<DatabaseType>Jellyfin-PostgreSQL</DatabaseType>
|
|
|
|
<CustomProviderOptions>
|
|
<PluginName>Jellyfin-PostgreSQL</PluginName>
|
|
<PluginAssembly>Jellyfin.Database.Providers.Postgres</PluginAssembly>
|
|
<ConnectionString>Host=localhost;Database=jellyfin;Username=jellyfin;Password=pwd</ConnectionString>
|
|
</CustomProviderOptions>
|
|
|
|
<BackupOptions>
|
|
<PgDumpPath>pg_dump</PgDumpPath>
|
|
<BackupFormat>custom</BackupFormat>
|
|
<CompressionLevel>6</CompressionLevel>
|
|
<IncludeBlobs>true</IncludeBlobs>
|
|
<TimeoutSeconds>1800</TimeoutSeconds>
|
|
<VerboseOutput>true</VerboseOutput>
|
|
</BackupOptions>
|
|
</DatabaseConfigurationOptions>
|
|
```
|
|
|
|
### Using the Service:
|
|
|
|
```csharp
|
|
// In your DI setup (Startup.cs or similar)
|
|
services.AddSingleton<PostgresBackupService>();
|
|
|
|
// In your code
|
|
public class BackupManager
|
|
{
|
|
private readonly PostgresBackupService _backupService;
|
|
|
|
public BackupManager(PostgresBackupService backupService)
|
|
{
|
|
_backupService = backupService;
|
|
}
|
|
|
|
public async Task PerformBackup()
|
|
{
|
|
// All settings are read from database.xml automatically
|
|
var backupPath = await _backupService.CreateBackupAsync("/backup/directory");
|
|
Console.WriteLine($"Backup created: {backupPath}");
|
|
}
|
|
|
|
public async Task RestoreFromBackup(string backupFile)
|
|
{
|
|
await _backupService.RestoreBackupAsync(backupFile);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Configuration Options
|
|
|
|
All options are **optional** with sensible defaults:
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `PgDumpPath` | string | Searches PATH | Path to pg_dump executable |
|
|
| `PgRestorePath` | string | Searches PATH | Path to pg_restore executable |
|
|
| `BackupFormat` | string | "custom" | Backup format: custom, plain, directory, tar |
|
|
| `IncludeBlobs` | bool | true | Include large objects in backup |
|
|
| `CompressionLevel` | int | 6 | Compression level (0-9) |
|
|
| `TimeoutSeconds` | int | 1800 | Max backup/restore time (30 min) |
|
|
| `VerboseOutput` | bool | true | Enable verbose logging |
|
|
| `ParallelJobs` | int? | null | Number of parallel jobs (directory format) |
|
|
| `AdditionalArguments` | string? | null | Extra pg_dump arguments |
|
|
|
|
## Benefits
|
|
|
|
1. **User-Configurable**: Users can customize backup behavior without code changes
|
|
2. **Flexible**: Supports all pg_dump formats and options
|
|
3. **Secure**: Uses environment variables for passwords
|
|
4. **Robust**: Includes timeout handling and error reporting
|
|
5. **Well-Documented**: Complete documentation for end users
|
|
6. **Backward Compatible**: All options have defaults, no configuration required for basic use
|
|
|
|
## Next Steps
|
|
|
|
To integrate this into Jellyfin:
|
|
|
|
1. **Register the Service** in your DI container:
|
|
```csharp
|
|
services.AddSingleton<PostgresBackupService>();
|
|
```
|
|
|
|
2. **Wire into existing backup system** (if Jellyfin has one):
|
|
```csharp
|
|
// In your backup manager/controller
|
|
if (dbType == "PostgreSQL")
|
|
{
|
|
var postgresBackup = serviceProvider.GetRequiredService<PostgresBackupService>();
|
|
await postgresBackup.CreateBackupAsync(backupDirectory);
|
|
}
|
|
```
|
|
|
|
3. **Add UI configuration** (optional):
|
|
- Create admin UI to edit backup options
|
|
- Save to database.xml through configuration manager
|
|
|
|
4. **Testing**:
|
|
- Test with different backup formats
|
|
- Test timeout handling
|
|
- Test restore operations
|
|
- Test path auto-detection on Windows/Linux
|
|
|
|
## Example Usage Scenarios
|
|
|
|
### Scenario 1: Basic Backup (default settings)
|
|
```xml
|
|
<BackupOptions>
|
|
<PgDumpPath>pg_dump</PgDumpPath>
|
|
</BackupOptions>
|
|
```
|
|
|
|
### Scenario 2: High Compression for Storage
|
|
```xml
|
|
<BackupOptions>
|
|
<BackupFormat>custom</BackupFormat>
|
|
<CompressionLevel>9</CompressionLevel>
|
|
<TimeoutSeconds>3600</TimeoutSeconds>
|
|
</BackupOptions>
|
|
```
|
|
|
|
### Scenario 3: Fast Parallel Backup
|
|
```xml
|
|
<BackupOptions>
|
|
<BackupFormat>directory</BackupFormat>
|
|
<ParallelJobs>4</ParallelJobs>
|
|
<CompressionLevel>3</CompressionLevel>
|
|
</BackupOptions>
|
|
```
|
|
|
|
### Scenario 4: Plain SQL Script
|
|
```xml
|
|
<BackupOptions>
|
|
<BackupFormat>plain</BackupFormat>
|
|
<AdditionalArguments>--exclude-schema=test</AdditionalArguments>
|
|
</BackupOptions>
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
1. **File Permissions**: Ensure `database.xml` is readable only by the Jellyfin user
|
|
2. **Backup Storage**: Store backups in a secure location with appropriate permissions
|
|
3. **Password Handling**: Uses `PGPASSWORD` environment variable (more secure than CLI args)
|
|
4. **Audit Logging**: All operations are logged with timestamps
|
|
|
|
## Troubleshooting
|
|
|
|
Common issues and solutions are documented in `BACKUP_CONFIGURATION.md`.
|