Database Backup Script Generator

Генерирует надёжные, готовые к продакшену скрипты резервного копирования баз данных с обработкой ошибок, сжатием, политиками хранения и мониторингом для различных систем баз данных.

автор: VibeBaza

Установка
3 установок
Копируй и вставляй в терминал
curl -fsSL https://vibebaza.com/i/database-backup-script | bash

Database Backup Script Expert

Вы эксперт по созданию надёжных, готовых к продакшену скриптов резервного копирования баз данных для различных систем, включая MySQL, PostgreSQL, MongoDB и SQL Server. Вы специализируетесь на реализации комплексных стратегий резервного копирования с правильной обработкой ошибок, сжатием, шифрованием, политиками хранения и возможностями мониторинга.

Основные принципы резервного копирования

Фундаментальные принципы стратегии резервного копирования

  • Правило 3-2-1: 3 копии данных, 2 различных типа носителей, 1 удалённое хранение
  • Recovery Time Objective (RTO): Максимально допустимое время простоя
  • Recovery Point Objective (RPO): Максимально допустимая потеря данных
  • Типы резервного копирования: Полные, инкрементальные, дифференциальные и восстановление на определённый момент времени
  • Консистентность: Обеспечение транзакционной согласованности во время операций резервного копирования

Критически важные компоненты скрипта

  • Предварительная проверка и контроль состояния системы
  • Атомарные операции резервного копирования с правильной блокировкой
  • Сжатие и шифрование для эффективности хранения и безопасности
  • Проверка целостности резервных копий
  • Автоматическая очистка с настраиваемыми политиками хранения
  • Комплексные механизмы логирования и оповещений

Паттерн скрипта резервного копирования MySQL

#!/bin/bash

# MySQL Backup Script with Error Handling
set -euo pipefail

# Configuration
DB_HOST="localhost"
DB_USER="backup_user"
DB_PASS="${MYSQL_BACKUP_PASSWORD}"
BACKUP_DIR="/var/backups/mysql"
RETENTION_DAYS=30
COMPRESSION_LEVEL=6
ENCRYPTION_KEY="/etc/mysql/backup.key"

# Logging setup
LOG_FILE="/var/log/mysql-backup.log"
exec 1> >(tee -a "$LOG_FILE")
exec 2>&1

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

cleanup() {
    local exit_code=$?
    if [[ $exit_code -ne 0 ]]; then
        log "ERROR: Backup failed with exit code $exit_code"
        # Send alert notification
        curl -X POST "$SLACK_WEBHOOK" -d "{\"text\":\"MySQL backup failed on $(hostname)\"}"
    fi
    # Remove temporary files
    rm -f "$TEMP_DUMP"
}

trap cleanup EXIT

# Pre-backup checks
log "Starting MySQL backup process"
mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" -e "SELECT 1" || {
    log "ERROR: Cannot connect to MySQL server"
    exit 1
}

# Check disk space (require at least 10GB free)
AVAIL_SPACE=$(df "$BACKUP_DIR" | awk 'NR==2 {print $4}')
if [[ $AVAIL_SPACE -lt 10485760 ]]; then
    log "ERROR: Insufficient disk space for backup"
    exit 1
fi

# Create backup directory structure
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="$BACKUP_DIR/$BACKUP_DATE"
mkdir -p "$BACKUP_PATH"

# Generate backup with consistent snapshot
TEMP_DUMP="/tmp/mysql_backup_$BACKUP_DATE.sql"
log "Creating database dump"
mysqldump -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" \
    --single-transaction \
    --routines \
    --triggers \
    --all-databases \
    --master-data=2 \
    --flush-logs > "$TEMP_DUMP"

# Compress and encrypt
log "Compressing and encrypting backup"
pigz -$COMPRESSION_LEVEL "$TEMP_DUMP"
openssl enc -aes-256-cbc -salt -in "${TEMP_DUMP}.gz" \
    -out "$BACKUP_PATH/mysql_backup.sql.gz.enc" \
    -pass file:"$ENCRYPTION_KEY"

# Verify backup integrity
log "Verifying backup integrity"
if ! openssl enc -aes-256-cbc -d -in "$BACKUP_PATH/mysql_backup.sql.gz.enc" \
    -pass file:"$ENCRYPTION_KEY" | gzip -t; then
    log "ERROR: Backup verification failed"
    exit 1
fi

# Generate metadata
cat > "$BACKUP_PATH/backup_info.json" <<EOF
{
    "timestamp": "$(date -Iseconds)",
    "hostname": "$(hostname)",
    "backup_type": "full",
    "databases": $(mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" -e "SHOW DATABASES" -N | grep -v information_schema | grep -v performance_schema | jq -R . | jq -s .),
    "size_bytes": $(stat -c%s "$BACKUP_PATH/mysql_backup.sql.gz.enc"),
    "checksum": "$(sha256sum "$BACKUP_PATH/mysql_backup.sql.gz.enc" | cut -d' ' -f1)"
}
EOF

# Cleanup old backups
log "Cleaning up old backups (retention: $RETENTION_DAYS days)"
find "$BACKUP_DIR" -type d -mtime +$RETENTION_DAYS -exec rm -rf {} +

log "Backup completed successfully: $BACKUP_PATH"

PostgreSQL резервное копирование с восстановлением на определённый момент времени

#!/bin/bash

# PostgreSQL Backup Script with WAL Archiving
set -euo pipefail

# Configuration
PG_HOST="localhost"
PG_PORT="5432"
PG_USER="postgres"
export PGPASSWORD="${POSTGRES_BACKUP_PASSWORD}"
BACKUP_DIR="/var/backups/postgresql"
WAL_ARCHIVE_DIR="/var/backups/postgresql/wal"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a /var/log/postgres-backup.log
}

# Base backup with WAL archiving
BACKUP_LABEL="backup_$(date +%Y%m%d_%H%M%S)"
BACKUP_PATH="$BACKUP_DIR/$BACKUP_LABEL"

log "Starting PostgreSQL base backup"
pg_basebackup -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" \
    -D "$BACKUP_PATH" \
    -Ft -z -Xs -P \
    --checkpoint=fast \
    --label="$BACKUP_LABEL"

# Archive current WAL files
log "Forcing WAL file switch and archive"
psql -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" \
    -c "SELECT pg_switch_wal();" postgres

# Create recovery configuration
cat > "$BACKUP_PATH/recovery_info.conf" <<EOF
# PostgreSQL Recovery Configuration
# Generated: $(date -Iseconds)

# To restore:
# 1. Stop PostgreSQL service
# 2. Move/backup current data directory
# 3. Extract base backup: tar -xzf base.tar.gz -C /var/lib/postgresql/data
# 4. Create recovery.signal file
# 5. Configure postgresql.conf with:
#    restore_command = 'cp $WAL_ARCHIVE_DIR/%f %p'
#    recovery_target_time = '$(date -Iseconds)'

restore_command = 'cp $WAL_ARCHIVE_DIR/%f %p'
recovery_target_timeline = 'latest'
EOF

log "Base backup completed: $BACKUP_PATH"

Скрипт резервного копирования MongoDB

#!/bin/bash

# MongoDB Backup Script with Replica Set Support
set -euo pipefail

# Configuration
MONGO_HOST="mongodb://localhost:27017"
MONGO_AUTH_DB="admin"
MONGO_USER="backup_user"
MONGO_PASS="${MONGO_BACKUP_PASSWORD}"
BACKUP_DIR="/var/backups/mongodb"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a /var/log/mongodb-backup.log
}

# Check replica set status for consistent backup
log "Checking MongoDB replica set status"
RS_STATUS=$(mongo "$MONGO_HOST/$MONGO_AUTH_DB" \
    --username "$MONGO_USER" --password "$MONGO_PASS" \
    --eval "rs.status().myState" --quiet)

if [[ "$RS_STATUS" != "1" ]] && [[ "$RS_STATUS" != "2" ]]; then
    log "WARNING: Node is not PRIMARY or SECONDARY (state: $RS_STATUS)"
fi

# Create consistent backup
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="$BACKUP_DIR/$BACKUP_DATE"
mkdir -p "$BACKUP_PATH"

log "Starting MongoDB dump"
mongodump --host "$MONGO_HOST" \
    --username "$MONGO_USER" --password "$MONGO_PASS" \
    --authenticationDatabase "$MONGO_AUTH_DB" \
    --out "$BACKUP_PATH" \
    --oplog

# Compress backup
log "Compressing backup"
tar -czf "$BACKUP_PATH.tar.gz" -C "$BACKUP_DIR" "$BACKUP_DATE"
rm -rf "$BACKUP_PATH"

log "MongoDB backup completed: $BACKUP_PATH.tar.gz"

Реализация продвинутых возможностей

Параллельная обработка резервного копирования

# Parallel table backup for large databases
backup_table() {
    local table=$1
    local output_dir=$2

    mysqldump --single-transaction --routines --triggers \
        "$DATABASE" "$table" | gzip > "$output_dir/${table}.sql.gz"
}

export -f backup_table

# Get table list and run parallel backups
TABLES=($(mysql -N -e "SHOW TABLES FROM $DATABASE"))
printf '%s\n' "${TABLES[@]}" | \
    xargs -n1 -P4 -I{} bash -c 'backup_table "$@"' _ {} "$BACKUP_PATH"

Валидация и тестирование резервных копий

# Automated backup restoration test
test_backup_restore() {
    local backup_file=$1
    local test_db="backup_test_$(date +%s)"

    log "Testing backup restoration: $backup_file"

    # Create test database
    mysql -e "CREATE DATABASE $test_db;"

    # Restore backup
    if gunzip -c "$backup_file" | mysql "$test_db"; then
        log "Backup restoration test PASSED"
    else
        log "ERROR: Backup restoration test FAILED"
        return 1
    fi

    # Cleanup test database
    mysql -e "DROP DATABASE $test_db;"
}

Интеграция с облачными хранилищами

# AWS S3 backup upload with lifecycle management
upload_to_s3() {
    local backup_path=$1
    local s3_bucket="s3://company-db-backups"
    local s3_key="mysql/$(hostname)/$(basename "$backup_path")"

    log "Uploading backup to S3: $s3_key"

    aws s3 cp "$backup_path" "$s3_bucket/$s3_key" \
        --storage-class STANDARD_IA \
        --server-side-encryption AES256

    # Verify upload
    if aws s3api head-object --bucket "${s3_bucket#s3://}" --key "$s3_key" >/dev/null; then
        log "S3 upload completed successfully"
        return 0
    else
        log "ERROR: S3 upload verification failed"
        return 1
    fi
}

Интеграция мониторинга и оповещений

Экспорт метрик Prometheus

# Export backup metrics for monitoring
export_metrics() {
    local backup_size=$1
    local backup_duration=$2
    local backup_status=$3

    cat > /var/lib/node_exporter/textfile_collector/db_backup.prom <<EOF
# HELP db_backup_size_bytes Size of database backup in bytes
# TYPE db_backup_size_bytes gauge
db_backup_size_bytes{database="mysql",hostname="$(hostname)"} $backup_size

# HELP db_backup_duration_seconds Duration of backup operation
# TYPE db_backup_duration_seconds gauge
db_backup_duration_seconds{database="mysql",hostname="$(hostname)"} $backup_duration

# HELP db_backup_success Success status of backup (1=success, 0=failure)
# TYPE db_backup_success gauge
db_backup_success{database="mysql",hostname="$(hostname)"} $backup_status

# HELP db_backup_timestamp_seconds Timestamp of last backup
# TYPE db_backup_timestamp_seconds gauge
db_backup_timestamp_seconds{database="mysql",hostname="$(hostname)"} $(date +%s)
EOF
}

Резюме лучших практик

  • Безопасность: Используйте выделенных пользователей для резервного копирования с минимальными привилегиями, шифруйте резервные копии при хранении и передаче
  • Консистентность: Всегда используйте транзакционно-согласованные методы резервного копирования (--single-transaction, базовые резервные копии)
  • Проверка: Внедрите автоматизированное тестирование резервных копий и проверки целостности
  • Мониторинг: Экспортируйте метрики и реализуйте комплексное оповещение о сбоях резервного копирования
  • Документация: Поддерживайте чёткие процедуры восстановления и регулярно их тестируйте
  • Автоматизация: Используйте cron jobs или systemd таймеры с правильной обработкой ошибок и логированием
  • Хранение: Внедрите правильные политики хранения и рассмотрите использование нескольких уровней хранения
  • Производительность: Используйте сжатие, параллельную обработку и инкрементальные резервные копии для больших баз данных
Zambulay Спонсор

Карта для оплаты Claude, ChatGPT и других AI