✋ Ручное резервное копирование

Процедуры ручного создания резервных копий для критических ситуаций

Когда нужно ручное резервное копирование

  • Перед критическими обновлениями системы
  • При миграции данных
  • Перед тестированием новых функций
  • В случае сбоя автоматических бэкапов
  • Для создания архивных копий

🗄️ Ручной бэкап базы данных

Полный бэкап PostgreSQL

# Базовая команда
sudo -u postgres pg_dump wiki_db > wiki_backup_$(date +%Y%m%d_%H%M%S).sql

# С сжатием
sudo -u postgres pg_dump wiki_db | gzip > wiki_backup_$(date +%Y%m%d_%H%M%S).sql.gz

# Кастомный формат (рекомендуется)
sudo -u postgres pg_dump -Fc wiki_db > wiki_backup_$(date +%Y%m%d_%H%M%S).dump

# С дополнительными опциями
sudo -u postgres pg_dump \
    --verbose \
    --no-owner \
    --no-privileges \
    --clean \
    --if-exists \
    wiki_db > wiki_backup_detailed_$(date +%Y%m%d_%H%M%S).sql

Бэкап с полными правами и схемой

# Включая роли и табличные пространства
sudo -u postgres pg_dumpall > full_cluster_backup_$(date +%Y%m%d_%H%M%S).sql

# Только схема без данных
sudo -u postgres pg_dump --schema-only wiki_db > schema_only_$(date +%Y%m%d_%H%M%S).sql

# Только данные без схемы
sudo -u postgres pg_dump --data-only wiki_db > data_only_$(date +%Y%m%d_%H%M%S).sql

# Бэкап конкретной таблицы
sudo -u postgres pg_dump --table=users wiki_db > users_table_$(date +%Y%m%d_%H%M%S).sql

Проверка созданного бэкапа

# Проверка размера
ls -lh wiki_backup_*.sql*

# Проверка содержимого (первые строки)
head -20 wiki_backup_*.sql

# Подсчет строк
wc -l wiki_backup_*.sql

# Проверка целостности сжатого файла
gzip -t wiki_backup_*.sql.gz && echo "Архив целый" || echo "Архив поврежден"

Ручной бэкап файлов

Создание архива системных файлов

# Создание базового архива
tar -czf system_backup_$(date +%Y%m%d_%H%M%S).tar.gz \
    /opt/wiki-iridium \
    /etc/nginx \
    /etc/ssl \
    --exclude='*.log' \
    --exclude='*.tmp'

# Создание архива с подробным выводом
tar -czvf detailed_backup_$(date +%Y%m%d_%H%M%S).tar.gz \
    /opt/wiki-iridium \
    /etc/nginx \
    /etc/ssl

# Архив с сохранением прав доступа
tar -czpf permissions_backup_$(date +%Y%m%d_%H%M%S).tar.gz \
    /opt/wiki-iridium

# Создание архива с проверкой
tar -czvf verified_backup_$(date +%Y%m%d_%H%M%S).tar.gz \
    /opt/wiki-iridium && \
tar -tzf verified_backup_$(date +%Y%m%d_%H%M%S).tar.gz > /dev/null && \
echo "Архив создан и проверен успешно"

Использование rsync для синхронизации

# Синхронизация с локальной директорией
rsync -av --delete /opt/wiki-iridium/ /backup/wiki-sync/

# Синхронизация с удаленным сервером
rsync -av --delete -e ssh /opt/wiki-iridium/ user@backup-server:/backup/wiki/

# Синхронизация с исключениями
rsync -av --delete \
    --exclude='*.log' \
    --exclude='*.tmp' \
    --exclude='__pycache__' \
    /opt/wiki-iridium/ /backup/wiki-clean/

# Синхронизация только измененных файлов
rsync -av --delete --checksum /opt/wiki-iridium/ /backup/wiki-checksum/

Интерактивный скрипт для ручного бэкапа

#!/bin/bash
# manual_backup_wizard.sh

echo " Мастер ручного резервного копирования Wiki Iridium"
echo "=================================================="

# Получение пользовательского ввода
read -p "Введите описание бэкапа: " DESCRIPTION
read -p "Создать бэкап базы данных? (y/n): " BACKUP_DB
read -p "Создать бэкап файлов? (y/n): " BACKUP_FILES
read -p "Путь для сохранения [/backup/manual]: " BACKUP_PATH

# Установка значений по умолчанию
BACKUP_PATH=${BACKUP_PATH:-/backup/manual}
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DESCRIPTION_SAFE=$(echo "$DESCRIPTION" | tr ' ' '_' | tr -cd '[:alnum:]_-')

# Создание директории
mkdir -p "$BACKUP_PATH"

echo ""
echo " Настройки бэкапа:"
echo "Описание: $DESCRIPTION"
echo "Путь: $BACKUP_PATH"
echo "Время: $(date)"
echo ""

# Функция логирования
log_file="$BACKUP_PATH/backup_${TIMESTAMP}.log"
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$log_file"
}

# Начало бэкапа
log "Начало ручного резервного копирования"
log "Описание: $DESCRIPTION"

# Бэкап базы данных
if [[ "$BACKUP_DB" =~ ^[Yy]$ ]]; then
    echo "🗄️ Создание бэкапа базы данных..."
    
    db_backup_file="$BACKUP_PATH/database_${DESCRIPTION_SAFE}_${TIMESTAMP}.dump"
    
    if sudo -u postgres pg_dump -Fc wiki_db > "$db_backup_file"; then
        log "Бэкап БД создан: $db_backup_file"
        
        # Проверка размера
        size=$(du -h "$db_backup_file" | cut -f1)
        log "Размер бэкапа БД: $size"
        
        # Быстрая проверка целостности
        if pg_restore --list "$db_backup_file" >/dev/null 2>&1; then
            log "Проверка целостности БД: УСПЕШНО"
        else
            log "ОШИБКА: Бэкап БД может быть поврежден"
        fi
    else
        log "ОШИБКА: Не удалось создать бэкап БД"
    fi
fi

# Бэкап файлов
if [[ "$BACKUP_FILES" =~ ^[Yy]$ ]]; then
    echo " Создание бэкапа файлов..."
    
    files_backup_file="$BACKUP_PATH/files_${DESCRIPTION_SAFE}_${TIMESTAMP}.tar.gz"
    
    if tar -czf "$files_backup_file" \
        /opt/wiki-iridium \
        /etc/nginx/sites-available \
        /etc/ssl/certs \
        --exclude='*.log' \
        --exclude='*.tmp' 2>>"$log_file"; then
        
        log "Бэкап файлов создан: $files_backup_file"
        
        # Проверка размера
        size=$(du -h "$files_backup_file" | cut -f1)
        log "Размер бэкапа файлов: $size"
        
        # Проверка целостности
        if tar -tzf "$files_backup_file" >/dev/null 2>&1; then
            log "Проверка целостности файлов: УСПЕШНО"
        else
            log "ОШИБКА: Архив файлов может быть поврежден"
        fi
    else
        log "ОШИБКА: Не удалось создать бэкап файлов"
    fi
fi

# Создание манифеста
manifest_file="$BACKUP_PATH/manifest_${TIMESTAMP}.txt"
cat > "$manifest_file" << EOF
МАНИФЕСТ РЕЗЕРВНОГО КОПИРОВАНИЯ
==============================

Дата создания: $(date)
Описание: $DESCRIPTION
Создатель: $(whoami)
Хост: $(hostname)

СОДЕРЖИМОЕ БЭКАПА:
EOF

if [[ "$BACKUP_DB" =~ ^[Yy]$ ]] && [ -f "$db_backup_file" ]; then
    echo "- База данных: $(basename "$db_backup_file") ($(du -h "$db_backup_file" | cut -f1))" >> "$manifest_file"
fi

if [[ "$BACKUP_FILES" =~ ^[Yy]$ ]] && [ -f "$files_backup_file" ]; then
    echo "- Файлы: $(basename "$files_backup_file") ($(du -h "$files_backup_file" | cut -f1))" >> "$manifest_file"
fi

echo "" >> "$manifest_file"
echo "СИСТЕМНАЯ ИНФОРМАЦИЯ:" >> "$manifest_file"
echo "- OS: $(lsb_release -d | cut -f2)" >> "$manifest_file"
echo "- Ядро: $(uname -r)" >> "$manifest_file"
echo "- Время работы: $(uptime -p)" >> "$manifest_file"

log "Создан манифест: $manifest_file"

# Подсчет общего размера
total_size=$(du -sh "$BACKUP_PATH" 2>/dev/null | cut -f1)
log "Общий размер бэкапа: $total_size"

log "Ручное резервное копирование завершено"

echo ""
echo " Резервное копирование завершено!"
echo " Файлы сохранены в: $BACKUP_PATH"
echo " Манифест: $manifest_file"
echo " Общий размер: $total_size"
echo ""
echo " Содержимое директории:"
ls -la "$BACKUP_PATH"/*${TIMESTAMP}*

📦 Экспорт конфигураций

Экспорт настроек Nginx

# Создание бэкапа конфигурации Nginx
mkdir -p /backup/configs/nginx_$(date +%Y%m%d)

# Копирование основных файлов
cp -r /etc/nginx/ /backup/configs/nginx_$(date +%Y%m%d)/

# Создание архива с конфигурацией
tar -czf /backup/configs/nginx_config_$(date +%Y%m%d_%H%M%S).tar.gz \
    /etc/nginx/ \
    /var/log/nginx/access.log \
    /var/log/nginx/error.log

# Экспорт только активных сайтов
cp /etc/nginx/sites-enabled/* /backup/configs/nginx_$(date +%Y%m%d)/ 2>/dev/null || true

Экспорт SSL сертификатов

# Создание бэкапа SSL сертификатов
mkdir -p /backup/ssl/$(date +%Y%m%d)

# Копирование сертификатов (будьте осторожны с приватными ключами!)
find /etc/ssl -name "*.crt" -exec cp {} /backup/ssl/$(date +%Y%m%d)/ \;
find /etc/ssl -name "*.key" -exec cp {} /backup/ssl/$(date +%Y%m%d)/ \;

# Создание зашифрованного архива
tar -czf - /etc/ssl/ | gpg -c > /backup/ssl/ssl_certificates_$(date +%Y%m%d_%H%M%S).tar.gz.gpg

🧪 Экстренное резервное копирование

Быстрый бэкап перед обновлением

#!/bin/bash
# emergency_backup.sh

echo " ЭКСТРЕННОЕ РЕЗЕРВНОЕ КОПИРОВАНИЕ"
echo "=================================="

EMERGENCY_DIR="/backup/emergency/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$EMERGENCY_DIR"

echo " Директория: $EMERGENCY_DIR"

# Критические данные
echo "🗄️ Бэкап базы данных..."
sudo -u postgres pg_dump -Fc wiki_db > "$EMERGENCY_DIR/emergency_db.dump"

echo " Бэкап критических файлов..."
tar -czf "$EMERGENCY_DIR/emergency_files.tar.gz" \
    /opt/wiki-iridium \
    /etc/nginx/sites-enabled \
    /etc/ssl/certs \
    --exclude='*.log'

echo " Экспорт системных настроек..."
# Список установленных пакетов
dpkg --get-selections > "$EMERGENCY_DIR/installed_packages.txt"

# Системная информация
uname -a > "$EMERGENCY_DIR/system_info.txt"
df -h >> "$EMERGENCY_DIR/system_info.txt"
free -h >> "$EMERGENCY_DIR/system_info.txt"

# Активные сервисы
systemctl list-units --type=service --state=running > "$EMERGENCY_DIR/running_services.txt"

echo " Экстренный бэкап завершен"
echo "📂 Размер: $(du -sh $EMERGENCY_DIR | cut -f1)"
ls -la "$EMERGENCY_DIR"

Проверка созданных бэкапов

Скрипт верификации

#!/bin/bash
# verify_manual_backup.sh

BACKUP_DIR="$1"

if [ -z "$BACKUP_DIR" ] || [ ! -d "$BACKUP_DIR" ]; then
    echo "Использование: $0 <путь_к_бэкапу>"
    exit 1
fi

echo " Проверка бэкапа в: $BACKUP_DIR"
echo "================================="

# Поиск файлов бэкапа
DB_BACKUP=$(find "$BACKUP_DIR" -name "*.dump" -o -name "*.sql" -o -name "*.sql.gz" | head -1)
FILES_BACKUP=$(find "$BACKUP_DIR" -name "*.tar.gz" | head -1)

# Проверка бэкапа БД
if [ -n "$DB_BACKUP" ]; then
    echo "🗄️ Проверка бэкапа БД: $(basename "$DB_BACKUP")"
    
    case "$DB_BACKUP" in
        *.dump)
            if pg_restore --list "$DB_BACKUP" >/dev/null 2>&1; then
                echo " Бэкап БД корректен"
                echo " Таблиц в бэкапе: $(pg_restore --list "$DB_BACKUP" | grep -c 'TABLE DATA')"
            else
                echo " Бэкап БД поврежден"
            fi
            ;;
        *.sql.gz)
            if gzip -t "$DB_BACKUP" 2>/dev/null; then
                echo " Сжатый SQL файл корректен"
            else
                echo " Сжатый SQL файл поврежден"
            fi
            ;;
        *.sql)
            if head -1 "$DB_BACKUP" | grep -q "PostgreSQL database dump"; then
                echo " SQL файл выглядит корректно"
            else
                echo " SQL файл может быть поврежден"
            fi
            ;;
    esac
    
    echo "📏 Размер: $(du -h "$DB_BACKUP" | cut -f1)"
else
    echo " Бэкап БД не найден"
fi

echo ""

# Проверка бэкапа файлов
if [ -n "$FILES_BACKUP" ]; then
    echo " Проверка бэкапа файлов: $(basename "$FILES_BACKUP")"
    
    if tar -tzf "$FILES_BACKUP" >/dev/null 2>&1; then
        echo " Архив файлов корректен"
        echo " Файлов в архиве: $(tar -tzf "$FILES_BACKUP" | wc -l)"
    else
        echo " Архив файлов поврежден"
    fi
    
    echo "📏 Размер: $(du -h "$FILES_BACKUP" | cut -f1)"
else
    echo " Бэкап файлов не найден"
fi

echo ""
echo " Содержимое директории бэкапа:"
ls -la "$BACKUP_DIR"

Чек-лист ручного бэкапа

Перед началом

  • Определить цель бэкапа
  • Выбрать тип бэкапа (полный/частичный)
  • Проверить доступное место
  • Уведомить пользователей (если нужно)

Во время бэкапа

  • Создать бэкап базы данных
  • Создать бэкап файлов
  • Проверить целостность
  • Записать логи операций

После бэкапа

  • Проверить размеры файлов
  • Провести тест восстановления
  • Создать манифест
  • Переместить в безопасное место
  • Обновить документацию

⚠️ Важные замечания

  1. Время - ручные бэкапы могут занимать много времени
  2. Ресурсы - следите за использованием CPU и диска
  3. Безопасность - не передавайте файлы бэкапов по незащищенным каналам
  4. Документирование - всегда создавайте манифесты и описания
  5. Тестирование - проверяйте возможность восстановления