🤖 Автоматическое резервное копирование
Настройка автоматизированных систем резервного копирования
Преимущества автоматизации
- Исключение человеческого фактора
- Соблюдение расписания
- Стандартизация процедур
- Снижение времени на обслуживание
Архитектура системы бэкапов
Компоненты системы
$$┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Источники │ ──▶│ Сценарии │ ──▶│ Хранилища │
│ данных │ │ резервного │ │ бэкапов │
│ │ │ копирования │ │ │
├─────────────────┤ ├──────────────────┤ ├─────────────────┤
│ • База данных │ │ • Полные бэкапы │ │ • Локальные │
│ • Файлы контента│ │ • Инкрементальные│ │ • Сетевые │
│ • Конфигурации │ │ • Сжатие/шифровка│ │ • Облачные │
│ • Логи │ │ • Верификация │ │ • Архивные │
└─────────────────┘ └──────────────────┘ └─────────────────┘$$
🗄️ Скрипт для бэкапа базы данных
#!/bin/bash
# postgresql_backup.sh
# Конфигурация
DB_NAME="wiki_db"
DB_USER="postgres"
BACKUP_DIR="/backup/postgresql"
RETENTION_DAYS=30
LOG_FILE="/var/log/backup/postgresql.log"
# Создание директорий
mkdir -p "$BACKUP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
# Функция логирования
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# Начало бэкапа
log "Начало резервного копирования базы данных $DB_NAME"
# Имя файла с временной меткой
BACKUP_FILE="$BACKUP_DIR/wiki_db_$(date +%Y%m%d_%H%M%S).sql"
# Создание бэкапа
if sudo -u postgres pg_dump "$DB_NAME" > "$BACKUP_FILE"; then
log "Бэкап базы данных создан: $BACKUP_FILE"
# Сжатие
if gzip "$BACKUP_FILE"; then
log "Бэкап сжат: ${BACKUP_FILE}.gz"
BACKUP_FILE="${BACKUP_FILE}.gz"
else
log "ОШИБКА: Не удалось сжать бэкап"
fi
# Проверка размера
SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
log "Размер бэкапа: $SIZE"
# Верификация (попытка восстановить в тестовую БД)
if command -v psql >/dev/null; then
TEST_DB="test_restore_$(date +%s)"
if sudo -u postgres createdb "$TEST_DB" && \
sudo -u postgres zcat "$BACKUP_FILE" | sudo -u postgres psql "$TEST_DB" >/dev/null 2>&1; then
log "Верификация бэкапа: УСПЕШНО"
sudo -u postgres dropdb "$TEST_DB"
else
log "ОШИБКА: Верификация бэкапа не удалась"
sudo -u postgres dropdb "$TEST_DB" 2>/dev/null
fi
fi
else
log "ОШИБКА: Не удалось создать бэкап базы данных"
exit 1
fi
# Очистка старых бэкапов
log "Очистка бэкапов старше $RETENTION_DAYS дней"
find "$BACKUP_DIR" -name "wiki_db_*.sql.gz" -mtime +$RETENTION_DAYS -delete
DELETED=$(find "$BACKUP_DIR" -name "wiki_db_*.sql.gz" -mtime +$RETENTION_DAYS 2>/dev/null | wc -l)
log "Удалено старых бэкапов: $DELETED"
# Проверка доступного места
AVAILABLE=$(df "$BACKUP_DIR" | awk 'NR==2 {print $4}')
if [ "$AVAILABLE" -lt 1048576 ]; then # Менее 1GB
log "ПРЕДУПРЕЖДЕНИЕ: Мало места для бэкапов: $(df -h "$BACKUP_DIR" | awk 'NR==2 {print $4}')"
fi
log "Резервное копирование базы данных завершено"
Скрипт для бэкапа файлов
#!/bin/bash
# files_backup.sh
# Конфигурация
SOURCE_DIRS=(
"/opt/wiki-iridium"
"/etc/nginx"
"/etc/ssl"
"/home"
)
BACKUP_DIR="/backup/files"
RETENTION_DAYS=14
LOG_FILE="/var/log/backup/files.log"
# Создание директорий
mkdir -p "$BACKUP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
# Функция логирования
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
log "Начало резервного копирования файлов"
# Создание архива
BACKUP_FILE="$BACKUP_DIR/files_$(date +%Y%m%d_%H%M%S).tar.gz"
# Исключения
EXCLUDE_FILE="/tmp/backup_exclude_$$"
cat > "$EXCLUDE_FILE" << EOF
*.log
*.tmp
*.cache
__pycache__
node_modules
.git
EOF
# Создание архива
if tar -czf "$BACKUP_FILE" \
--exclude-from="$EXCLUDE_FILE" \
"${SOURCE_DIRS[@]}" 2>>"$LOG_FILE"; then
log "Архив создан: $BACKUP_FILE"
# Размер архива
SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
log "Размер архива: $SIZE"
# Верификация архива
if tar -tzf "$BACKUP_FILE" >/dev/null 2>&1; then
log "Верификация архива: УСПЕШНО"
else
log "ОШИБКА: Архив поврежден"
fi
else
log "ОШИБКА: Не удалось создать архив"
rm -f "$EXCLUDE_FILE"
exit 1
fi
# Очистка
rm -f "$EXCLUDE_FILE"
# Очистка старых бэкапов
log "Очистка архивов старше $RETENTION_DAYS дней"
find "$BACKUP_DIR" -name "files_*.tar.gz" -mtime +$RETENTION_DAYS -delete
log "Резервное копирование файлов завершено"
Мастер-скрипт для полного бэкапа
#!/bin/bash
# full_backup.sh
SCRIPT_DIR="/opt/backup-scripts"
LOG_FILE="/var/log/backup/full_backup.log"
# Функция логирования
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# Функция отправки уведомлений
send_notification() {
local status="$1"
local message="$2"
# Email уведомление
echo "$message" | mail -s "Бэкап $(hostname): $status" admin@company.com
# Slack/Discord webhook (опционально)
# curl -X POST -H 'Content-type: application/json' \
# --data '{"text":"'"$message"'"}' \
# YOUR_WEBHOOK_URL
}
log "=== НАЧАЛО ПОЛНОГО РЕЗЕРВНОГО КОПИРОВАНИЯ ==="
# Массив скриптов для выполнения
BACKUP_SCRIPTS=(
"$SCRIPT_DIR/postgresql_backup.sh"
"$SCRIPT_DIR/files_backup.sh"
)
SUCCESS_COUNT=0
TOTAL_COUNT=${#BACKUP_SCRIPTS[@]}
# Выполнение скриптов
for script in "${BACKUP_SCRIPTS[@]}"; do
if [ -x "$script" ]; then
log "Выполнение: $script"
if "$script"; then
log "УСПЕШНО: $script"
((SUCCESS_COUNT++))
else
log "ОШИБКА: $script"
fi
else
log "ПРОПУЩЕН: $script (не найден или не исполняемый)"
fi
done
# Дополнительные проверки
log "Проверка свободного места"
BACKUP_USAGE=$(du -sh /backup 2>/dev/null | cut -f1)
DISK_USAGE=$(df -h /backup 2>/dev/null | awk 'NR==2 {print $5}')
log "Использование: /backup = $BACKUP_USAGE, диск = $DISK_USAGE"
# Итоговый отчет
if [ "$SUCCESS_COUNT" -eq "$TOTAL_COUNT" ]; then
STATUS="УСПЕШНО"
MESSAGE="Все бэкапы ($SUCCESS_COUNT/$TOTAL_COUNT) выполнены успешно"
else
STATUS="ЧАСТИЧНО"
MESSAGE="Выполнено $SUCCESS_COUNT из $TOTAL_COUNT бэкапов"
fi
log "$MESSAGE"
log "=== ЗАВЕРШЕНИЕ ПОЛНОГО РЕЗЕРВНОГО КОПИРОВАНИЯ ==="
# Отправка уведомления
send_notification "$STATUS" "$MESSAGE"
# Код возврата
[ "$SUCCESS_COUNT" -eq "$TOTAL_COUNT" ]
📅 Настройка Cron
# Редактирование crontab
sudo crontab -e
# Ежедневный бэкап в 2:00
0 2 * * * /opt/backup-scripts/full_backup.sh
# Проверка состояния бэкапов каждые 6 часов
0 */6 * * * /opt/backup-scripts/check_backups.sh
# Еженедельная очистка в воскресенье в 3:00
0 3 * * 0 /opt/backup-scripts/cleanup_old_backups.sh
# Ежемесячное тестирование восстановления (первое воскресенье месяца)
0 4 1-7 * 0 /opt/backup-scripts/test_restore.sh
Скрипт мониторинга бэкапов
#!/bin/bash
# check_backups.sh
BACKUP_DIR="/backup"
LOG_FILE="/var/log/backup/monitoring.log"
ALERT_EMAIL="admin@company.com"
# Функция логирования
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# Функция алерта
alert() {
local message="$1"
log "АЛЕРТ: $message"
echo "$message" | mail -s " Алерт бэкапа $(hostname)" "$ALERT_EMAIL"
}
log "Начало проверки состояния бэкапов"
# Проверка последнего бэкапа БД
LAST_DB_BACKUP=$(find "$BACKUP_DIR/postgresql" -name "*.sql.gz" -mtime -1 | head -1)
if [ -z "$LAST_DB_BACKUP" ]; then
alert "Нет свежего бэкапа базы данных (последние 24 часа)"
else
log "Найден свежий бэкап БД: $(basename "$LAST_DB_BACKUP")"
fi
# Проверка последнего бэкапа файлов
LAST_FILES_BACKUP=$(find "$BACKUP_DIR/files" -name "*.tar.gz" -mtime -1 | head -1)
if [ -z "$LAST_FILES_BACKUP" ]; then
alert "Нет свежего бэкапа файлов (последние 24 часа)"
else
log "Найден свежий бэкап файлов: $(basename "$LAST_FILES_BACKUP")"
fi
# Проверка доступного места (менее 10% = алерт)
DISK_USAGE=$(df "$BACKUP_DIR" | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt 90 ]; then
alert "Критически мало места для бэкапов: ${DISK_USAGE}%"
elif [ "$DISK_USAGE" -gt 80 ]; then
log "ПРЕДУПРЕЖДЕНИЕ: Мало места для бэкапов: ${DISK_USAGE}%"
fi
# Проверка целостности последних бэкапов
if [ -n "$LAST_DB_BACKUP" ]; then
if ! gzip -t "$LAST_DB_BACKUP" 2>/dev/null; then
alert "Поврежден последний бэкап БД: $(basename "$LAST_DB_BACKUP")"
fi
fi
if [ -n "$LAST_FILES_BACKUP" ]; then
if ! tar -tzf "$LAST_FILES_BACKUP" >/dev/null 2>&1; then
alert "Поврежден последний бэкап файлов: $(basename "$LAST_FILES_BACKUP")"
fi
fi
log "Проверка состояния бэкапов завершена"
Безопасность автоматических бэкапов
Ограничение прав доступа
#!/bin/bash
# setup_backup_security.sh
# Создание пользователя для бэкапов
sudo useradd -r -s /bin/bash -d /var/lib/backup backup-user
# Настройка директорий
sudo mkdir -p /backup/{postgresql,files}
sudo mkdir -p /var/log/backup
sudo mkdir -p /opt/backup-scripts
# Права доступа
sudo chown -R backup-user:backup-user /backup
sudo chown -R backup-user:backup-user /var/log/backup
sudo chown -R backup-user:backup-user /opt/backup-scripts
sudo chmod 750 /backup
sudo chmod 750 /var/log/backup
sudo chmod 755 /opt/backup-scripts
# Добавление в группу postgres для доступа к БД
sudo usermod -a -G postgres backup-user
# Настройка sudo для backup-user
echo "backup-user ALL=(postgres) NOPASSWD: /usr/bin/pg_dump, /usr/bin/createdb, /usr/bin/dropdb, /usr/bin/psql" | sudo tee /etc/sudoers.d/backup-user
Шифрование бэкапов
#!/bin/bash
# encrypted_backup.sh
# Конфигурация
GPG_RECIPIENT="admin@company.com"
BACKUP_DIR="/backup/encrypted"
# Функция шифрования
encrypt_backup() {
local source_file="$1"
local encrypted_file="${source_file}.gpg"
if gpg --trust-model always --encrypt \
--recipient "$GPG_RECIPIENT" \
--output "$encrypted_file" \
"$source_file"; then
echo "Зашифрован: $encrypted_file"
rm "$source_file" # Удаляем незашифрованную версию
return 0
else
echo "ОШИБКА: Не удалось зашифровать $source_file"
return 1
fi
}
# Пример использования
BACKUP_FILE="/backup/postgresql/wiki_db_$(date +%Y%m%d_%H%M%S).sql.gz"
# ... создание бэкапа ...
encrypt_backup "$BACKUP_FILE"
Оптимизация производительности
Сжатие и параллелизм
#!/bin/bash
# optimized_backup.sh
# Использование pigz для параллельного сжатия
if command -v pigz >/dev/null; then
GZIP_CMD="pigz"
else
GZIP_CMD="gzip"
fi
# Параллельное создание разных типов бэкапов
(
echo "Запуск бэкапа БД..."
/opt/backup-scripts/postgresql_backup.sh
) &
(
echo "Запуск бэкапа файлов..."
/opt/backup-scripts/files_backup.sh
) &
# Ожидание завершения всех процессов
wait
echo "Все бэкапы завершены"
Лучшие практики
- Мониторинг - всегда проверяйте успешность бэкапов
- Тестирование - регулярно проверяйте восстановление
- Логирование - ведите подробные логи всех операций
- Уведомления - настройте алерты при сбоях
- Безопасность - ограничьте доступ и используйте шифрование
- Производительность - оптимизируйте время выполнения
- Мониторинг ресурсов - следите за использованием диска и сети