#!/bin/bash # Database backup script with S3 upload # Runs every 12 hours and keeps last 7 local backups BACKUP_DIR="/backups" DB_HOST="${DB_HOST:-db}" DB_USER="${DB_USER:-root}" DB_PASSWORD="${MYSQL_ROOT_PASSWORD}" KEEP_BACKUPS="${KEEP_BACKUPS:-7}" S3_BUCKET="${S3_BUCKET:-selectel:backup_db}" S3_PATH="${S3_PATH:-dot}" ENVIRONMENT="${ENVIRONMENT:-prod}" while true; do echo "[$(date)] Starting database backup process..." # Get list of databases (exclude system databases) DATABASES=$(mysql -h "${DB_HOST}" -u"${DB_USER}" -p"${DB_PASSWORD}" -s -AN -e 'show databases' | grep -vE "information_schema|performance_schema|sys") if [ $? -ne 0 ]; then echo "[$(date)] ERROR: Failed to get database list!" sleep 43200 continue fi # Backup each database separately for database in ${DATABASES}; do TIMESTAMP=$(date +%Y%m%d_%H%M%S) DAY_NAME=$(date +%a) BACKUP_FILE="${BACKUP_DIR}/${database}.${DAY_NAME}.sql.gz" echo "[$(date)] Backing up database: ${database}..." # Create backup with compression (MariaDB compatible) mysqldump -h "${DB_HOST}" \ -u"${DB_USER}" \ -p"${DB_PASSWORD}" \ --max-allowed-packet=1G \ --add-drop-table \ --single-transaction \ --extended-insert \ --quick \ --lock-tables=false \ --skip-add-locks \ --skip-comments \ "${database}" | gzip -c > "${BACKUP_FILE}" if [ $? -eq 0 ]; then # Get file size for logging BACKUP_SIZE=$(du -h "${BACKUP_FILE}" | cut -f1) echo "[$(date)] Backup completed: ${database} (${BACKUP_SIZE})" # Upload to S3 if rclone is configured if [ -f /root/.config/rclone/rclone.conf ]; then echo "[$(date)] Uploading ${database} to S3..." rclone copy "${BACKUP_FILE}" "${S3_BUCKET}/${S3_PATH}/${ENVIRONMENT}/" --progress if [ $? -eq 0 ]; then echo "[$(date)] Successfully uploaded ${database} to S3" # Optional: remove local backup after successful upload # rm -f "${BACKUP_FILE}" else echo "[$(date)] WARNING: Failed to upload ${database} to S3" fi else echo "[$(date)] Rclone not configured, keeping backup locally only" fi else echo "[$(date)] ERROR: Failed to backup ${database}!" [ -f "${BACKUP_FILE}" ] && rm -f "${BACKUP_FILE}" fi done # Clean old local backups (keep last N days for each database) echo "[$(date)] Cleaning old local backups..." for database in ${DATABASES}; do ls -t ${BACKUP_DIR}/${database}.*.sql.gz 2>/dev/null | tail -n +$((KEEP_BACKUPS + 1)) | xargs -r rm -f done # List current backups echo "[$(date)] Current local backups:" ls -lah ${BACKUP_DIR}/*.sql.gz 2>/dev/null || echo "No backups found" echo "[$(date)] Next backup will run in 12 hours..." echo "=========================================" # Sleep for 12 hours (43200 seconds) sleep 43200 done