#!/bin/bash ############################################################################### # Database Backup Script for MariaDB # # Features: # - Dumps all databases from MariaDB # - Compresses backups with gzip # - Rotates backups to keep only 7 days of backups # - Logs all operations with timestamps # - Handles errors gracefully ############################################################################### # Use 'set -a' to export all variables (important for password with special chars) set -a # Source environment if it exists if [ -f "/mnt/HC_Volume_103713257/tilbudgivern/backend/.env" ]; then source "/mnt/HC_Volume_103713257/tilbudgivern/backend/.env" fi set +a set -euo pipefail # Configuration BACKUP_DIR="/mnt/HC_Volume_103713257/tilbudgivern/backups" LOG_FILE="/mnt/HC_Volume_103713257/tilbudgivern/logs/backups/backup.log" RETENTION_DAYS=7 # Use environment variables with defaults MYSQL_USER="${DB_BACKUP_USER:-tilbudgivern_service}" MYSQL_PASSWORD="${DB_BACKUP_PASSWORD:-}" MYSQL_HOST="${DB_BACKUP_HOST:-127.0.0.1}" # Ensure directories exist mkdir -p "$BACKUP_DIR" mkdir -p "$(dirname "$LOG_FILE")" # Logging function log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # Error handler error_exit() { log "ERROR: $1" exit 1 } # Start backup log "==========================================" log "Starting database backup process" log "==========================================" # Create timestamp for backup file TIMESTAMP=$(date '+%Y%m%d_%H%M%S') BACKUP_FILE="$BACKUP_DIR/mariadb_all_databases_${TIMESTAMP}.sql" COMPRESSED_FILE="${BACKUP_FILE}.gz" # Check if mysqldump is available if ! command -v mysqldump &> /dev/null; then error_exit "mysqldump command not found. Please ensure MySQL client is installed." fi # Create mysqldump command MYSQLDUMP_CMD="mysqldump --user=$MYSQL_USER" if [ -n "$MYSQL_PASSWORD" ]; then MYSQLDUMP_CMD="$MYSQLDUMP_CMD --password=$MYSQL_PASSWORD" fi MYSQLDUMP_CMD="$MYSQLDUMP_CMD --host=$MYSQL_HOST --all-databases --single-transaction --quick --lock-tables=false" # Perform backup log "Dumping all databases from $MYSQL_HOST..." if $MYSQLDUMP_CMD > "$BACKUP_FILE"; then UNCOMPRESSED_SIZE=$(du -h "$BACKUP_FILE" | cut -f1) log "Database dump completed successfully. Size: $UNCOMPRESSED_SIZE" else rm -f "$BACKUP_FILE" error_exit "Failed to create database dump" fi # Compress backup log "Compressing backup file..." if gzip "$BACKUP_FILE"; then COMPRESSED_SIZE=$(du -h "$COMPRESSED_FILE" | cut -f1) log "Backup compressed successfully. Size: $COMPRESSED_SIZE" log "Backup saved to: $COMPRESSED_FILE" else error_exit "Failed to compress backup file" fi # Rotate backups - keep only 7 most recent log "Rotating backups (keeping $RETENTION_DAYS days)..." ROTATION_COUNT=0 while [ $(find "$BACKUP_DIR" -name "mariadb_all_databases_*.sql.gz" -type f | wc -l) -gt $RETENTION_DAYS ]; do OLDEST_BACKUP=$(find "$BACKUP_DIR" -name "mariadb_all_databases_*.sql.gz" -type f -printf '%T@ %p\n' | sort -n | head -1 | cut -d' ' -f2-) log "Removing old backup: $(basename "$OLDEST_BACKUP")" rm -f "$OLDEST_BACKUP" ((ROTATION_COUNT++)) done if [ $ROTATION_COUNT -gt 0 ]; then log "Rotated $ROTATION_COUNT backup(s)" fi # Display current backups log "Current backups in system:" ls -lh "$BACKUP_DIR"/*.gz 2>/dev/null | awk '{print " " $9 " (" $5 ")"}' | tee -a "$LOG_FILE" || log "No backups found" # Summary log "==========================================" log "Backup process completed successfully" log "==========================================" exit 0