✋ Ручное резервное копирование
Процедуры ручного создания резервных копий для критических ситуаций
Когда нужно ручное резервное копирование
- Перед критическими обновлениями системы
- При миграции данных
- Перед тестированием новых функций
- В случае сбоя автоматических бэкапов
- Для создания архивных копий
🗄️ Ручной бэкап базы данных
Полный бэкап 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"
Чек-лист ручного бэкапа
Перед началом
- Определить цель бэкапа
- Выбрать тип бэкапа (полный/частичный)
- Проверить доступное место
- Уведомить пользователей (если нужно)
Во время бэкапа
- Создать бэкап базы данных
- Создать бэкап файлов
- Проверить целостность
- Записать логи операций
После бэкапа
- Проверить размеры файлов
- Провести тест восстановления
- Создать манифест
- Переместить в безопасное место
- Обновить документацию
⚠️ Важные замечания
- Время - ручные бэкапы могут занимать много времени
- Ресурсы - следите за использованием CPU и диска
- Безопасность - не передавайте файлы бэкапов по незащищенным каналам
- Документирование - всегда создавайте манифесты и описания
- Тестирование - проверяйте возможность восстановления