feat: Refactor backup script to initialize performance log file and ensure full backups every time

This commit is contained in:
Peter Wood
2025-05-26 09:13:32 -04:00
parent 1149e9656c
commit 1d01ca8c61
2 changed files with 50 additions and 93 deletions

View File

@@ -23,9 +23,10 @@ MAX_BACKUPS_TO_KEEP=10
BACKUP_ROOT="/mnt/share/media/backups/plex" BACKUP_ROOT="/mnt/share/media/backups/plex"
LOG_ROOT="/mnt/share/media/backups/logs" LOG_ROOT="/mnt/share/media/backups/logs"
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
JSON_LOG_FILE="${SCRIPT_DIR}/logs/plex-backup.json"
PERFORMANCE_LOG_FILE="${SCRIPT_DIR}/logs/plex-backup-performance.json" PERFORMANCE_LOG_FILE="${SCRIPT_DIR}/logs/plex-backup-performance.json"
# Backup strategy configuration - Always perform full backups
# Plex SQLite path (custom Plex SQLite binary) # Plex SQLite path (custom Plex SQLite binary)
PLEX_SQLITE="/usr/lib/plexmediaserver/Plex SQLite" PLEX_SQLITE="/usr/lib/plexmediaserver/Plex SQLite"
@@ -81,6 +82,7 @@ while [[ $# -gt 0 ]]; do
echo " --webhook=URL Send notifications to webhook URL" echo " --webhook=URL Send notifications to webhook URL"
echo " --email=ADDRESS Send notifications to email address" echo " --email=ADDRESS Send notifications to email address"
echo " -h, --help Show this help message" echo " -h, --help Show this help message"
echo ""
exit 0 exit 0
;; ;;
*) *)
@@ -170,48 +172,15 @@ track_performance() {
log_info "Performance: $operation completed in ${duration}s" log_info "Performance: $operation completed in ${duration}s"
} }
# Initialize JSON log file # Initialize log directory
initialize_json_log() { initialize_logs() {
if [ ! -f "${JSON_LOG_FILE}" ] || ! jq empty "${JSON_LOG_FILE}" 2>/dev/null; then mkdir -p "$(dirname "$PERFORMANCE_LOG_FILE")"
echo "{}" > "${JSON_LOG_FILE}" if [ ! -f "$PERFORMANCE_LOG_FILE" ]; then
log_message "Initialized JSON log file" echo "[]" > "$PERFORMANCE_LOG_FILE"
log_message "Initialized performance log file"
fi fi
} }
# Check if file needs backup based on modification time
needs_backup() {
local file="$1"
if [ ! -f "$file" ]; then
log_warning "File not found: $file"
return 1
fi
local current_mod_date=$(stat -c %Y "$file")
local last_backup_date=$(jq -r --arg file "$file" '.[$file] // 0' "${JSON_LOG_FILE}")
if [ "$last_backup_date" == "null" ] || [ "$last_backup_date" == "0" ]; then
log_message "File has never been backed up: $(basename "$file")"
return 0
fi
if [ "$current_mod_date" -gt "$last_backup_date" ]; then
log_message "File modified since last backup: $(basename "$file")"
return 0
fi
log_message "File unchanged since last backup: $(basename "$file")"
return 1
}
# Update backup time in JSON log
update_backup_time() {
local file="$1"
local timestamp="$2"
jq --arg file "$file" --arg timestamp "$timestamp" '.[$file] = ($timestamp | tonumber)' "${JSON_LOG_FILE}" > "${JSON_LOG_FILE}.tmp" && mv "${JSON_LOG_FILE}.tmp" "${JSON_LOG_FILE}"
}
# Enhanced notification system # Enhanced notification system
send_notification() { send_notification() {
local title="$1" local title="$1"
@@ -754,7 +723,7 @@ estimate_backup_size() {
for nickname in "${!PLEX_FILES[@]}"; do for nickname in "${!PLEX_FILES[@]}"; do
local file="${PLEX_FILES[$nickname]}" local file="${PLEX_FILES[$nickname]}"
if [ -f "$file" ] && needs_backup "$file" >/dev/null 2>&1; then if [ -f "$file" ]; then
local size_kb=$(du -k "$file" 2>/dev/null | cut -f1) local size_kb=$(du -k "$file" 2>/dev/null | cut -f1)
total_size=$((total_size + size_kb)) total_size=$((total_size + size_kb))
fi fi
@@ -907,8 +876,8 @@ main() {
mkdir -p "${BACKUP_ROOT}" mkdir -p "${BACKUP_ROOT}"
mkdir -p "${LOG_ROOT}" mkdir -p "${LOG_ROOT}"
# Initialize JSON log # Initialize logs
initialize_json_log initialize_logs
# Check if only doing integrity check # Check if only doing integrity check
if [ "$INTEGRITY_CHECK_ONLY" = true ]; then if [ "$INTEGRITY_CHECK_ONLY" = true ]; then
@@ -983,43 +952,34 @@ main() {
# Handle WAL files backup # Handle WAL files backup
handle_wal_files "backup" "$BACKUP_PATH" handle_wal_files "backup" "$BACKUP_PATH"
# Backup files # Backup files - always perform full backup
local backup_start=$(date +%s) local backup_start=$(date +%s)
for nickname in "${!PLEX_FILES[@]}"; do for nickname in "${!PLEX_FILES[@]}"; do
local file="${PLEX_FILES[$nickname]}" local file="${PLEX_FILES[$nickname]}"
if [ -f "$file" ]; then if [ -f "$file" ]; then
if needs_backup "$file" ]; then log_message "Backing up: $(basename "$file")"
log_message "Backing up: $(basename "$file")"
# Create backup filename without timestamp (use original filename)
local backup_file="${BACKUP_PATH}/$(basename "$file")"
# Copy file
if sudo cp "$file" "$backup_file"; then
log_success "Copied: $(basename "$file")"
# Create backup filename without timestamp (use original filename) # Verify backup
local backup_file="${BACKUP_PATH}/$(basename "$file")" if verify_backup "$file" "$backup_file"; then
log_success "Verified: $(basename "$file")"
# Copy file files_backed_up=$((files_backed_up + 1))
if sudo cp "$file" "$backup_file"; then
log_success "Copied: $(basename "$file")"
# Verify backup
if verify_backup "$file" "$backup_file"; then
log_success "Verified: $(basename "$file")"
# Update backup time in JSON log
local current_timestamp=$(date +%s)
update_backup_time "$file" "$current_timestamp"
files_backed_up=$((files_backed_up + 1))
else
log_error "Verification failed: $(basename "$file")"
backup_errors=$((backup_errors + 1))
# Remove failed backup
rm -f "$backup_file"
fi
else else
log_error "Failed to copy: $(basename "$file")" log_error "Verification failed: $(basename "$file")"
backup_errors=$((backup_errors + 1)) backup_errors=$((backup_errors + 1))
# Remove failed backup
rm -f "$backup_file"
fi fi
else else
log_message "Skipping unchanged file: $(basename "$file")" log_error "Failed to copy: $(basename "$file")"
backup_errors=$((backup_errors + 1))
fi fi
else else
log_warning "File not found: $file" log_warning "File not found: $file"

View File

@@ -1,24 +1,34 @@
# Enhanced Plex Backup Script Documentation # 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. This document provides comprehensive documentation for the enhanced `backup-plex.sh` script. This advanced backup solution includes performance monitoring, parallel processing, intelligent notifications, and WAL file handling.
## Script Overview ## Script Overview
The enhanced script performs the following advanced tasks: The enhanced script performs the following advanced tasks:
1. **Performance Monitoring**: Tracks backup operations with JSON-based performance logging 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 2. **Full Backup Operations**: Performs complete backups of all Plex files every time
3. **WAL File Handling**: Properly handles SQLite Write-Ahead Logging files 3. **WAL File Handling**: Properly handles SQLite Write-Ahead Logging files
4. **Database Integrity Verification**: Comprehensive integrity checks with automated repair options 4. **Database Integrity Verification**: Comprehensive integrity checks with automated repair options
5. **Parallel Processing**: Concurrent verification for improved performance 5. **Parallel Processing**: Concurrent verification for improved performance
6. **Multi-Channel Notifications**: Console, webhook, and email notification support 6. **Multi-Channel Notifications**: Console, webhook, and email notification support
7. **Checksum Caching**: Intelligent caching to avoid recalculating unchanged file checksums 7. **Enhanced Service Management**: Safe Plex service management with progress indicators
8. **Enhanced Service Management**: Safe Plex service management with progress indicators 8. **Comprehensive Logging**: Detailed logs with color-coded output and timestamps
9. **Comprehensive Logging**: Detailed logs with color-coded output and timestamps 9. **Safe Automated Cleanup**: Retention policies based on age and backup count
10. **Automated Cleanup**: Configurable retention policies for old backups
## Enhanced Features ## Enhanced Features
### Full Backup Operation
The script performs complete backups every time it runs:
- **What it does**: Backs up all Plex files regardless of modification status
- **Benefits**:
- Guarantees every backup is a complete restoration point
- Eliminates risk of file loss from incomplete backup coverage
- Simplifies backup management and restoration
- **Usage**: `./backup-plex.sh` (no options needed)
### Performance Tracking ### Performance Tracking
- **JSON Performance Logs**: All operations are timed and logged to `logs/plex-backup-performance.json` - **JSON Performance Logs**: All operations are timed and logged to `logs/plex-backup-performance.json`
@@ -208,17 +218,6 @@ The performance log (`logs/plex-backup-performance.json`) contains entries like:
] ]
``` ```
### Backup Tracking Log
The backup tracking log (`logs/plex-backup.json`) tracks last backup times:
```json
{
"/var/lib/plexmediaserver/.../com.plexapp.plugins.library.db": 1732567523,
"/var/lib/plexmediaserver/.../Preferences.xml": 1732567523
}
```
## Usage Examples ## Usage Examples
### Basic Backup ### Basic Backup
@@ -406,15 +405,14 @@ The enhanced script implements a robust backup strategy with a streamlined tar.g
The new backup system eliminates intermediate dated directories and stores only compressed archives: The new backup system eliminates intermediate dated directories and stores only compressed archives:
```bash ```text
/mnt/share/media/backups/plex/ /mnt/share/media/backups/plex/
├── plex-backup-20250125_143022.tar.gz # Latest backup ├── plex-backup-20250125_143022.tar.gz # Latest backup
├── plex-backup-20250124_143011.tar.gz # Previous backup ├── plex-backup-20250124_143011.tar.gz # Previous backup
├── plex-backup-20250123_143008.tar.gz # Older backup ├── plex-backup-20250123_143008.tar.gz # Older backup
└── logs/ └── logs/
├── backup_log_20250125_143022.md ├── backup_log_20250125_143022.md
── plex-backup-performance.json ── plex-backup-performance.json
└── plex-backup.json
``` ```
### Archive Naming Convention ### Archive Naming Convention
@@ -434,15 +432,14 @@ Backup files follow the naming convention `plex-backup-YYYYMMDD_HHMMSS.tar.gz` f
## Final Directory Structure ## Final Directory Structure
``` ```text
/mnt/share/media/backups/plex/ /mnt/share/media/backups/plex/
├── plex-backup-20250125_143022.tar.gz # Latest backup ├── plex-backup-20250125_143022.tar.gz # Latest backup
├── plex-backup-20250124_143011.tar.gz # Previous backup ├── plex-backup-20250124_143011.tar.gz # Previous backup
├── plex-backup-20250123_143008.tar.gz # Older backup ├── plex-backup-20250123_143008.tar.gz # Older backup
└── logs/ └── logs/
├── backup_log_20250125_143022.md ├── backup_log_20250125_143022.md
── plex-backup-performance.json ── plex-backup-performance.json
└── plex-backup.json
``` ```
Backup files follow the pattern: `plex-backup-YYYYMMDD_HHMMSS.tar.gz` Backup files follow the pattern: `plex-backup-YYYYMMDD_HHMMSS.tar.gz`