backupdb/scripts/backup-db.sh

88 lines
3.1 KiB
Bash

#!/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|mysql")
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
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 \
"${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