Скрипт для бэкапа PostgreSQL в Docker с выгрузкой на Яндекс.Диск
#!/bin/bash
# Конфигурация
BACKUP_DIR="/site/backup"
DB_USER="имя_пользователя"
DB_NAME="имя_базы"
CONTAINER_NAME="имя_контейнера"
RCLONE_REMOTE="yandex"
RCLONE_PATH="/backups"
LOG_FILE="/site/backup.log"
LOCAL_RETENTION_DAYS=7
REMOTE_RETENTION_DAYS=30
MAX_RETRIES=3 # Максимальное количество попыток для rclone
# Создаем директорию для бэкапов
mkdir -p "${BACKUP_DIR}"
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
# Функция для логирования
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "${LOG_FILE}"
}
# Функция для повторных попыток загрузки
upload_with_retry() {
local file=$1
local attempts=0
while [ $attempts -lt $MAX_RETRIES ]; do
rclone copy "$file" "${RCLONE_REMOTE}:${RCLONE_PATH}" --log-file "${LOG_FILE}" --log-level ERROR
if [ $? -eq 0 ]; then
return 0
fi
attempts=$((attempts+1))
log "Попытка $attempts/$MAX_RETRIES не удалась, повтор через 30 секунд..."
sleep 30
done
return 1
}
# 1. SQL-бэкап (сжатый gzip)
SQL_BACKUP_CREATED=false
SQL_BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.sql.gz"
log "Создание SQL бэкапа: ${SQL_BACKUP_FILE}"
docker exec -i "${CONTAINER_NAME}" pg_dump -U "${DB_USER}" -d "${DB_NAME}" | gzip > "${SQL_BACKUP_FILE}"
if [ $? -eq 0 ]; then
log "SQL бэкап успешно создан (размер: $(du -h "${SQL_BACKUP_FILE}" | cut -f1))"
SQL_BACKUP_CREATED=true
else
log "ОШИБКА: Не удалось создать SQL бэкап!"
rm -f "${SQL_BACKUP_FILE}"
fi
# 2. Custom-бэкап (для pgAdmin)
CUSTOM_BACKUP_CREATED=false
CUSTOM_BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.backup"
log "Создание Custom бэкапа: ${CUSTOM_BACKUP_FILE}"
TEMP_BACKUP_FILE="${CUSTOM_BACKUP_FILE}.tmp"
docker exec -i "${CONTAINER_NAME}" pg_dump -U "${DB_USER}" -Fc -d "${DB_NAME}" > "${TEMP_BACKUP_FILE}"
if [ $? -eq 0 ]; then
if docker exec -i "${CONTAINER_NAME}" pg_restore -l -Fc < "${TEMP_BACKUP_FILE}" > /dev/null 2>&1; then
mv "${TEMP_BACKUP_FILE}" "${CUSTOM_BACKUP_FILE}"
log "Custom бэкап успешно создан (размер: $(du -h "${CUSTOM_BACKUP_FILE}" | cut -f1))"
CUSTOM_BACKUP_CREATED=true
else
log "ОШИБКА: Custom бэкап повреждён или пуст!"
fi
else
log "ОШИБКА: Не удалось создать Custom бэкап!"
fi
rm -f "${TEMP_BACKUP_FILE}"
# 3. Копирование на Яндекс.Диск (только успешных бэкапов)
UPLOAD_ERROR=0
if $SQL_BACKUP_CREATED; then
log "Загрузка SQL бэкапа на Яндекс.Диск..."
upload_with_retry "${SQL_BACKUP_FILE}"
if [ $? -ne 0 ]; then
log "ОШИБКА: Не удалось загрузить SQL бэкап после $MAX_RETRIES попыток"
UPLOAD_ERROR=1
fi
fi
if $CUSTOM_BACKUP_CREATED; then
log "Загрузка Custom бэкапа на Яндекс.Диск..."
upload_with_retry "${CUSTOM_BACKUP_FILE}"
if [ $? -ne 0 ]; then
log "ОШИБКА: Не удалось загрузить Custom бэкап после $MAX_RETRIES попыток"
UPLOAD_ERROR=1
fi
fi
if [ $SQL_BACKUP_CREATED = true ] && [ $CUSTOM_BACKUP_CREATED = true ]; then
if [ $UPLOAD_ERROR -eq 0 ]; then
log "Оба бэкапа успешно загружены на Яндекс.Диск"
else
log "Частичная загрузка: один из бэкапов не загружен"
fi
elif [ $SQL_BACKUP_CREATED = true ] || [ $CUSTOM_BACKUP_CREATED = true ]; then
log "Загружен только один бэкап из двух"
fi
# 4. Очистка старых бэкапов
log "Очистка локальных бэкапов (старше ${LOCAL_RETENTION_DAYS} дней)"
find "${BACKUP_DIR}" -name "${DB_NAME}_*.sql.gz" -type f -mtime +${LOCAL_RETENTION_DAYS} -delete
find "${BACKUP_DIR}" -name "${DB_NAME}_*.backup" -type f -mtime +${LOCAL_RETENTION_DAYS} -delete
log "Очистка удалённых бэкапов (старше ${REMOTE_RETENTION_DAYS} дней)"
rclone delete "${RCLONE_REMOTE}:${RCLONE_PATH}" --min-age ${REMOTE_RETENTION_DAYS}d --include "*.sql.gz" --log-file "${LOG_FILE}" --log-level ERROR
rclone delete "${RCLONE_REMOTE}:${RCLONE_PATH}" --min-age ${REMOTE_RETENTION_DAYS}d --include "*.backup" --log-file "${LOG_FILE}" --log-level ERROR
# Итоговый отчёт
log "Резервное копирование завершено"
log "Статус:"
log " - SQL бэкап: $([ $SQL_BACKUP_CREATED = true ] && echo "Успешно" || echo "Не создан")"
log " - Custom бэкап: $([ $CUSTOM_BACKUP_CREATED = true ] && echo "Успешно" || echo "Не создан")"
log " - Загрузка: $([ $UPLOAD_ERROR -eq 0 ] && echo "Успешно" || echo "С ошибками")"
Категория: Администрирование |автор: fominyh_vv
Опубликовано: 22-05-2025 14:33
Комментарии (0)
Пока нет комментариев. Будьте первым!
Чтобы оставить комментарий, пожалуйста войдите или зарегистрируйтесь.