Files
shell/docs/plex-backup.md

16 KiB

Enhanced Plex Backup Script Documentation

This document provides comprehensive documentation for the enhanced backup-plex.sh script. This advanced backup solution includes performance monitoring, parallel processing, intelligent notifications, WAL file handling, and automated testing capabilities.

Script Overview

The enhanced script performs the following advanced tasks:

  1. Performance Monitoring: Tracks backup operations with JSON-based performance logging
  2. Intelligent Backup Detection: Only backs up files that have changed since last backup
  3. WAL File Handling: Properly handles SQLite Write-Ahead Logging files
  4. Database Integrity Verification: Comprehensive integrity checks with automated repair options
  5. Parallel Processing: Concurrent verification for improved performance
  6. Multi-Channel Notifications: Console, webhook, and email notification support
  7. Checksum Caching: Intelligent caching to avoid recalculating unchanged file checksums
  8. Enhanced Service Management: Safe Plex service management with progress indicators
  9. Comprehensive Logging: Detailed logs with color-coded output and timestamps
  10. Automated Cleanup: Configurable retention policies for old backups

Enhanced Features

Performance Tracking

  • JSON Performance Logs: All operations are timed and logged to logs/plex-backup-performance.json
  • Performance Reports: Automatic generation of average performance metrics
  • Operation Monitoring: Tracks backup, verification, service management, and overall script execution times

Notification System

The script supports multiple notification channels:

Console Notifications

  • Color-coded status messages (Success: Green, Error: Red, Warning: Yellow, Info: Blue)
  • Timestamped log entries with clear formatting

Webhook Notifications

./backup-plex.sh --webhook=https://your-webhook-url.com/endpoint

Sends JSON payloads with backup status, hostname, and timestamps.

Email Notifications

./backup-plex.sh --email=admin@example.com

Requires sendmail to be configured on the system.

WAL File Management

The script now properly handles SQLite Write-Ahead Logging files:

  • Automatic Detection: Identifies and backs up .db-wal and .db-shm files when present
  • WAL Checkpointing: Performs PRAGMA wal_checkpoint(FULL) before integrity checks
  • Safe Backup: Ensures WAL files are properly backed up alongside main database files

Database Integrity & Repair

Enhanced database management features:

  • Pre-backup Integrity Checks: Verifies database health before backup operations
  • Automated Repair: Optional automatic repair of corrupted databases using advanced techniques
  • Interactive Repair Mode: Prompts for repair decisions when issues are detected
  • Post-repair Verification: Re-checks integrity after repair operations

Parallel Processing

  • Concurrent Verification: Parallel backup verification for improved performance
  • Fallback Safety: Automatically falls back to sequential processing if parallel mode fails
  • Configurable: Can be disabled with --no-parallel for maximum safety

Command Line Options

Usage: ./backup-plex.sh [OPTIONS]

Options:
  --auto-repair        Automatically attempt to repair corrupted databases
  --check-integrity    Only check database integrity, don't backup
  --non-interactive    Run in non-interactive mode (for automation)
  --no-parallel        Disable parallel verification (slower but safer)
  --no-performance     Disable performance monitoring
  --webhook=URL        Send notifications to webhook URL
  --email=ADDRESS      Send notifications to email address
  -h, --help          Show help message

Detailed Backup Process Steps

The backup script follows these detailed steps to ensure data integrity and reliability:

1. Create Log Directory

mkdir -p /mnt/share/media/backups/logs || { echo "Failed to create log directory"; exit 1; }

This command ensures that the log directory exists. If it doesn't, it creates the directory. If the directory creation fails, the script exits with an error message.

2. Define Log File

LOG_FILE="/mnt/share/media/backups/logs/backup_log_$(date +%Y%m%d_%H%M%S).md"

This line defines the log file path, including the current date and time in the filename to ensure uniqueness.

3. Stop Plex Media Server Service

if systemctl is-active --quiet plexmediaserver.service; then
  /home/acedanger/shell/plex.sh stop || { echo "Failed to stop plexmediaserver.service"; exit 1; }
fi

This block checks if the Plex Media Server service is running. If it is, the script stops the service using a custom script (plex.sh).

4. Backup Plex Database Files and Preferences

The enhanced backup system creates compressed archives directly, eliminating intermediate directories:

# Files are copied to temporary staging area for verification
cp "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db" "$BACKUP_PATH/"
cp "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.blobs.db" "$BACKUP_PATH/"
cp "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Preferences.xml" "$BACKUP_PATH/"

These commands copy the Plex database files and preferences directly to the backup root directory. Each file copy operation includes integrity verification and checksum validation.

5. Create Compressed Archive

# Create archive directly with timestamp naming convention
final_archive="${BACKUP_ROOT}/plex-backup-$(date '+%Y%m%d_%H%M%S').tar.gz"
tar -czf "$final_archive" -C "$temp_staging_dir" .

The system creates compressed archives directly using a timestamp-based naming convention (plex-backup-YYYYMMDD_HHMMSS.tar.gz), eliminating the need for intermediate dated directories.

6. Archive Validation and Cleanup

# Validate archive integrity
if tar -tzf "$final_archive" >/dev/null 2>&1; then
    log_success "Archive created and validated: $(basename "$final_archive")"
    rm -rf "$temp_staging_dir"
else
    log_error "Archive validation failed"
    rm -f "$final_archive"
fi

The system validates the created archive and removes temporary staging files, ensuring only valid compressed backups are retained in the backup root directory.

7. Send Notification

curl \
    -H tags:popcorn,backup,plex,${HOSTNAME} \
    -d "The Plex databases have been saved to the /media/backups/plex folder as plex-backup-YYYYMMDD_HHMMSS.tar.gz" \
    https://notify.peterwood.rocks/lab || { echo "Failed to send notification"; exit 1; }

This command sends a notification upon completion of the backup process, indicating the compressed archive has been created.

8. Restart Plex Media Server Service

if systemctl is-enabled --quiet plexmediaserver.service; then
  /home/acedanger/shell/plex.sh start || { echo "Failed to start plexmediaserver.service"; exit 1; }
fi

This block checks if the Plex Media Server service is enabled. If it is, the script restarts the service using a custom script (plex.sh).

9. Legacy Cleanup

# Clean up any remaining dated directories from old backup structure
find "${BACKUP_ROOT}" -maxdepth 1 -type d -name "????????" -exec rm -rf {} \; 2>/dev/null || true

The enhanced system includes cleanup of legacy dated directories from previous backup structure versions, ensuring a clean tar.gz-only backup directory.

Configuration Files

Performance Log Format

The performance log (logs/plex-backup-performance.json) contains entries like:

[
  {
    "operation": "backup",
    "duration_seconds": 45.3,
    "timestamp": "2025-05-25T19:45:23-05:00"
  },
  {
    "operation": "verification",
    "duration_seconds": 12.8,
    "timestamp": "2025-05-25T19:46:08-05:00"
  }
]

Backup Tracking Log

The backup tracking log (logs/plex-backup.json) tracks last backup times:

{
  "/var/lib/plexmediaserver/.../com.plexapp.plugins.library.db": 1732567523,
  "/var/lib/plexmediaserver/.../Preferences.xml": 1732567523
}

Usage Examples

Basic Backup

./backup-plex.sh

Performs a standard backup with all enhanced features enabled.

Integrity Check Only

./backup-plex.sh --check-integrity

Only checks database integrity without performing backup.

Automated Backup with Notifications

./backup-plex.sh --non-interactive --auto-repair --webhook=https://notify.example.com/backup

Runs in automated mode with auto-repair and webhook notifications.

Performance-Optimized Backup

./backup-plex.sh --no-parallel --no-performance

Runs with parallel processing and performance monitoring disabled for maximum compatibility.

Automation and Scheduling

Cron Job Setup

For daily automated backups at 2 AM:

# Edit crontab
crontab -e

# Add this line for daily backup
0 2 * * * /home/acedanger/shell/backup-plex.sh --non-interactive --auto-repair --email=admin@example.com 2>&1 | logger -t plex-backup

Systemd Service

Create a systemd service for more control:

[Unit]
Description=Plex Backup Service
After=network.target

[Service]
Type=oneshot
User=root
ExecStart=/home/acedanger/shell/backup-plex.sh --non-interactive --auto-repair
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Systemd Timer

Create a timer for regular execution:

[Unit]
Description=Daily Plex Backup
Requires=plex-backup.service

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Monitoring and Alerts

Performance Monitoring

The script automatically tracks:

  • Backup operation duration
  • Verification times
  • Service start/stop times
  • Overall script execution time

Health Checks

Regular health monitoring can be implemented by checking:

# Check last backup success
jq -r '.[-1] | select(.operation == "total_script") | .timestamp' logs/plex-backup-performance.json

# Check average backup performance
jq '[.[] | select(.operation == "backup") | .duration_seconds] | add/length' logs/plex-backup-performance.json

Troubleshooting

Common Issues

  1. Permission Denied Errors

    • Ensure script runs with appropriate sudo permissions
    • Check Plex file ownership and permissions
  2. WAL File Warnings

    • Now handled automatically by the enhanced script
    • WAL checkpointing ensures data consistency
  3. Performance Issues

    • Use --no-parallel if concurrent operations cause problems
    • Monitor performance logs for bottlenecks
  4. Notification Failures

    • Verify webhook URLs are accessible
    • Check sendmail configuration for email notifications

Debug Mode

Enable verbose logging by modifying the script or using:

bash -x ./backup-plex.sh --check-integrity

Testing Framework

The script includes a comprehensive testing framework (test-plex-backup.sh):

Running Tests

# Run all tests
./test-plex-backup.sh all

# Run only unit tests
./test-plex-backup.sh unit

# Run performance benchmarks
./test-plex-backup.sh performance

Test Categories

  • Unit Tests: Core functionality verification
  • Integration Tests: Full system testing (requires Plex installation)
  • Performance Tests: Benchmarking and performance validation

Security Considerations

File Permissions

  • Backup files are created with appropriate permissions
  • Sensitive files maintain original ownership and permissions
  • Temporary files are properly cleaned up

Network Security

  • Webhook notifications use HTTPS when possible
  • Email notifications respect system sendmail configuration
  • No sensitive data is included in notifications

Access Control

  • Script requires appropriate sudo permissions
  • Backup locations should have restricted access
  • Log files contain operational data, not sensitive information

Backup Strategy

The enhanced script implements a robust backup strategy with a streamlined tar.gz-only structure:

Archive-Only Directory Structure

The new backup system eliminates intermediate dated directories and stores only compressed archives:

/mnt/share/media/backups/plex/
├── plex-backup-20250125_143022.tar.gz    # Latest backup
├── plex-backup-20250124_143011.tar.gz    # Previous backup
├── plex-backup-20250123_143008.tar.gz    # Older backup
└── logs/
    ├── backup_log_20250125_143022.md
    ├── plex-backup-performance.json
    └── plex-backup.json

Archive Naming Convention

Backup files follow the naming convention plex-backup-YYYYMMDD_HHMMSS.tar.gz for easy identification and sorting.

Important Information

  • Ensure that the plex.sh script is available and executable. This script is used to stop and start the Plex Media Server service.
  • The script uses systemctl to manage the Plex Media Server service. Ensure that systemctl is available on your system.
  • New Directory Structure: The enhanced backup system stores only compressed .tar.gz files directly in the backup root directory, eliminating intermediate dated directories.
  • Archive Naming: Backup files follow the naming convention plex-backup-YYYYMMDD_HHMMSS.tar.gz for easy identification and sorting.
  • Legacy Compatibility: The system automatically cleans up old dated directories from previous backup versions during operation.
  • The backup directory path is configurable through the BACKUP_ROOT variable. Modify this path as needed to fit your environment.
  • The script logs important actions and errors to timestamped log files. Check the log files for details if any issues arise.
  • Backup Validation: All archives undergo integrity checking to ensure backup reliability.

Final Directory Structure

/mnt/share/media/backups/plex/
├── plex-backup-20250125_143022.tar.gz    # Latest backup
├── plex-backup-20250124_143011.tar.gz    # Previous backup  
├── plex-backup-20250123_143008.tar.gz    # Older backup
└── logs/
    ├── backup_log_20250125_143022.md
    ├── plex-backup-performance.json
    └── plex-backup.json

Backup files follow the pattern: plex-backup-YYYYMMDD_HHMMSS.tar.gz

  • YYYYMMDD: Date of backup (e.g., 20250125)
  • HHMMSS: Time of backup (e.g., 143022)
  • tar.gz: Compressed archive format

Key Improvements

  1. Direct Archive Creation: No intermediate directories required
  2. Efficient Storage: Only compressed files stored permanently
  3. Easy Identification: Timestamp-based naming for sorting
  4. Legacy Cleanup: Automatic removal of old dated directories
  5. Archive Validation: Integrity checking of compressed files

3-2-1 Backup Rule

  1. 3 Copies: Original data + local backup + compressed archive
  2. 2 Different Media: Local disk + network storage capability
  3. 1 Offsite: Ready for remote synchronization

Retention Policy

  • Configurable maximum backup age (default: 30 days)
  • Configurable maximum backup count (default: 10 backups)
  • Automatic cleanup of old backups

Verification Strategy

  • Checksum verification for all backed up files
  • Database integrity checks before and after operations
  • Optional parallel verification for improved performance

Migration from Legacy Script

To migrate from the original backup script:

  1. Backup Current Configuration: Save any custom modifications
  2. Test New Script: Run with --check-integrity first
  3. Update Automation: Modify cron jobs to use new options
  4. Monitor Performance: Check performance logs for optimization opportunities

The enhanced script maintains backward compatibility while adding significant new capabilities.