Резервное копирование ботов
В этой статье мы рассмотрим стратегии резервного копирования ботов, включая автоматические бэкапы, восстановление данных и мониторинг целостности резервных копий.Содержание
- Стратегии резервного копирования
- Автоматические бэкапы
- Резервное копирование баз данных
- Облачное хранение
- Восстановление данных
- Мониторинг и тестирование
- Аварийное восстановление
Стратегии резервного копирования
Типы резервного копирования
# Полное резервное копирование (Full Backup)
- Копирование всех данных
- Большой размер, медленное восстановление
- Используется для еженедельных/месячных бэкапов
# Инкрементальное резервное копирование (Incremental Backup)
- Копирование только измененных данных
- Быстрое выполнение, экономия места
- Требует полного бэкапа для восстановления
# Дифференциальное резервное копирование (Differential Backup)
- Копирование данных с последнего полного бэкапа
- Компромисс между полным и инкрементальным
- Быстрее полного, но медленнее инкрементального
Планирование стратегии
# backup_strategy.py
from datetime import datetime, timedelta
import os
import shutil
import gzip
import tarfile
class BackupStrategy:
def __init__(self, backup_dir="/backups"):
self.backup_dir = backup_dir
self.retention_policy = {
'daily': 7, # 7 дней
'weekly': 4, # 4 недели
'monthly': 12 # 12 месяцев
}
def create_full_backup(self, source_paths, backup_name):
"""Создание полного бэкапа"""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_file = f"{backup_name}_full_{timestamp}.tar.gz"
backup_path = os.path.join(self.backup_dir, backup_file)
with tarfile.open(backup_path, "w:gz") as tar:
for source_path in source_paths:
if os.path.exists(source_path):
tar.add(source_path, arcname=os.path.basename(source_path))
return backup_path
def create_incremental_backup(self, source_paths, backup_name, last_backup_time):
"""Создание инкрементального бэкапа"""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_file = f"{backup_name}_inc_{timestamp}.tar.gz"
backup_path = os.path.join(self.backup_dir, backup_file)
with tarfile.open(backup_path, "w:gz") as tar:
for source_path in source_paths:
if os.path.exists(source_path):
for root, dirs, files in os.walk(source_path):
for file in files:
file_path = os.path.join(root, file)
file_mtime = datetime.fromtimestamp(os.path.getmtime(file_path))
if file_mtime > last_backup_time:
tar.add(file_path, arcname=os.path.relpath(file_path, source_path))
return backup_path
def cleanup_old_backups(self, backup_name):
"""Очистка старых бэкапов"""
backup_files = [f for f in os.listdir(self.backup_dir) if f.startswith(backup_name)]
backup_files.sort()
# Удаление старых бэкапов согласно политике хранения
for retention_type, count in self.retention_policy.items():
if retention_type == 'daily':
# Оставляем последние N ежедневных бэкапов
daily_backups = [f for f in backup_files if 'full' in f or 'inc' in f]
if len(daily_backups) > count:
for old_backup in daily_backups[:-count]:
os.remove(os.path.join(self.backup_dir, old_backup))
# Использование
strategy = BackupStrategy()
backup_path = strategy.create_full_backup(
['/home/botuser/telegram-bot', '/home/botuser/discord-bot'],
'bots_backup'
)
print(f"Backup created: {backup_path}")Автоматические бэкапы
Скрипт автоматического бэкапа
#!/bin/bash
# auto-backup.sh
# Конфигурация
BACKUP_DIR="/backups"
BOT_DIRS=("/home/botuser/telegram-bot" "/home/botuser/discord-bot" "/home/botuser/vk-bot")
DB_NAME="bot_database"
DB_USER="bot_user"
DB_PASS="bot_password"
RETENTION_DAYS=7
# Создание директории для бэкапов
mkdir -p $BACKUP_DIR
# Функция логирования
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $BACKUP_DIR/backup.log
}
# Функция создания бэкапа
create_backup() {
local backup_name="bot_backup_$(date +%Y%m%d_%H%M%S)"
local backup_path="$BACKUP_DIR/$backup_name"
log "Начинаем создание бэкапа: $backup_name"
# Создание директории для бэкапа
mkdir -p $backup_path
# Бэкап файлов ботов
for bot_dir in "${BOT_DIRS[@]}"; do
if [ -d "$bot_dir" ]; then
log "Копирование $bot_dir"
cp -r "$bot_dir" "$backup_path/"
else
log "Предупреждение: $bot_dir не найден"
fi
done
# Бэкап базы данных
log "Создание бэкапа базы данных"
pg_dump -h localhost -U $DB_USER -d $DB_NAME > "$backup_path/database.sql"
# Создание архива
log "Создание архива"
tar -czf "$backup_path.tar.gz" -C $BACKUP_DIR $backup_name
rm -rf $backup_path
log "Бэкап завершен: $backup_path.tar.gz"
echo $backup_path.tar.gz
}
# Функция очистки старых бэкапов
cleanup_old_backups() {
log "Очистка старых бэкапов (старше $RETENTION_DAYS дней)"
find $BACKUP_DIR -name "bot_backup_*.tar.gz" -mtime +$RETENTION_DAYS -delete
}
# Функция проверки целостности
verify_backup() {
local backup_file=$1
log "Проверка целостности: $backup_file"
if tar -tzf "$backup_file" > /dev/null 2>&1; then
log "Бэкап корректен: $backup_file"
return 0
else
log "Ошибка: Бэкап поврежден: $backup_file"
return 1
fi
}
# Основная функция
main() {
log "=== Начало автоматического бэкапа ==="
# Создание бэкапа
backup_file=$(create_backup)
if [ $? -eq 0 ]; then
# Проверка целостности
if verify_backup "$backup_file"; then
log "Бэкап успешно создан и проверен"
# Очистка старых бэкапов
cleanup_old_backups
# Отправка уведомления об успехе
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Backup completed successfully: '$backup_file'"}' \
https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
else
log "Ошибка: Бэкап поврежден"
exit 1
fi
else
log "Ошибка создания бэкапа"
exit 1
fi
log "=== Завершение автоматического бэкапа ==="
}
# Запуск
main "$@"Cron настройка
# Добавление в crontab
# Ежедневный бэкап в 2:00
0 2 * /usr/local/bin/auto-backup.sh
# Еженедельный полный бэкап в воскресенье в 1:00
0 1 0 /usr/local/bin/auto-backup.sh --full
# Ежемесячный бэкап 1 числа в 0:00
0 0 1 /usr/local/bin/auto-backup.sh --monthlyРезервное копирование баз данных
PostgreSQL бэкап
# database_backup.py
import subprocess
import os
import gzip
from datetime import datetime
import logging
class DatabaseBackup:
def __init__(self, db_config):
self.db_config = db_config
self.logger = logging.getLogger(__name__)
def create_postgresql_backup(self, backup_path):
"""Создание бэкапа PostgreSQL"""
try:
# Команда pg_dump
cmd = [
'pg_dump',
'-h', self.db_config['host'],
'-U', self.db_config['user'],
'-d', self.db_config['database'],
'-f', backup_path,
'--verbose',
'--no-password'
]
# Установка переменной окружения для пароля
env = os.environ.copy()
env['PGPASSWORD'] = self.db_config['password']
# Выполнение команды
result = subprocess.run(cmd, env=env, capture_output=True, text=True)
if result.returncode == 0:
self.logger.info(f"PostgreSQL backup created: {backup_path}")
return True
else:
self.logger.error(f"PostgreSQL backup failed: {result.stderr}")
return False
except Exception as e:
self.logger.error(f"Error creating PostgreSQL backup: {e}")
return False
def create_mysql_backup(self, backup_path):
"""Создание бэкапа MySQL"""
try:
# Команда mysqldump
cmd = [
'mysqldump',
'-h', self.db_config['host'],
'-u', self.db_config['user'],
f'-p{self.db_config["password"]}',
self.db_config['database'],
'--single-transaction',
'--routines',
'--triggers'
]
# Выполнение команды
with open(backup_path, 'w') as f:
result = subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE, text=True)
if result.returncode == 0:
self.logger.info(f"MySQL backup created: {backup_path}")
return True
else:
self.logger.error(f"MySQL backup failed: {result.stderr}")
return False
except Exception as e:
self.logger.error(f"Error creating MySQL backup: {e}")
return False
def create_sqlite_backup(self, db_path, backup_path):
"""Создание бэкапа SQLite"""
try:
import sqlite3
# Подключение к базе данных
source = sqlite3.connect(db_path)
backup = sqlite3.connect(backup_path)
# Создание бэкапа
source.backup(backup)
# Закрытие соединений
backup.close()
source.close()
self.logger.info(f"SQLite backup created: {backup_path}")
return True
except Exception as e:
self.logger.error(f"Error creating SQLite backup: {e}")
return False
def compress_backup(self, backup_path):
"""Сжатие бэкапа"""
try:
compressed_path = f"{backup_path}.gz"
with open(backup_path, 'rb') as f_in:
with gzip.open(compressed_path, 'wb') as f_out:
f_out.writelines(f_in)
# Удаление несжатого файла
os.remove(backup_path)
self.logger.info(f"Backup compressed: {compressed_path}")
return compressed_path
except Exception as e:
self.logger.error(f"Error compressing backup: {e}")
return backup_path
# Использование
db_backup = DatabaseBackup({
'host': 'localhost',
'user': 'bot_user',
'password': 'bot_password',
'database': 'bot_database'
})
backup_path = f"/backups/db_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.sql"
if db_backup.create_postgresql_backup(backup_path):
compressed_path = db_backup.compress_backup(backup_path)
print(f"Database backup created: {compressed_path}")Облачное хранение
Интеграция с AWS S3
# cloud_backup.py
import boto3
import os
from datetime import datetime
import logging
class CloudBackup:
def __init__(self, aws_config):
self.aws_config = aws_config
self.s3_client = boto3.client(
's3',
aws_access_key_id=aws_config['access_key'],
aws_secret_access_key=aws_config['secret_key'],
region_name=aws_config['region']
)
self.logger = logging.getLogger(__name__)
def upload_to_s3(self, local_file_path, s3_key):
"""Загрузка файла в S3"""
try:
self.s3_client.upload_file(
local_file_path,
self.aws_config['bucket'],
s3_key
)
self.logger.info(f"File uploaded to S3: {s3_key}")
return True
except Exception as e:
self.logger.error(f"Error uploading to S3: {e}")
return False
def download_from_s3(self, s3_key, local_file_path):
"""Скачивание файла из S3"""
try:
self.s3_client.download_file(
self.aws_config['bucket'],
s3_key,
local_file_path
)
self.logger.info(f"File downloaded from S3: {s3_key}")
return True
except Exception as e:
self.logger.error(f"Error downloading from S3: {e}")
return False
def list_backups(self, prefix="bot_backup_"):
"""Список бэкапов в S3"""
try:
response = self.s3_client.list_objects_v2(
Bucket=self.aws_config['bucket'],
Prefix=prefix
)
backups = []
if 'Contents' in response:
for obj in response['Contents']:
backups.append({
'key': obj['Key'],
'size': obj['Size'],
'last_modified': obj['LastModified']
})
return backups
except Exception as e:
self.logger.error(f"Error listing backups: {e}")
return []
def delete_old_backups(self, retention_days=30):
"""Удаление старых бэкапов"""
try:
backups = self.list_backups()
cutoff_date = datetime.now() - timedelta(days=retention_days)
for backup in backups:
if backup['last_modified'].replace(tzinfo=None) < cutoff_date:
self.s3_client.delete_object(
Bucket=self.aws_config['bucket'],
Key=backup['key']
)
self.logger.info(f"Deleted old backup: {backup['key']}")
return True
except Exception as e:
self.logger.error(f"Error deleting old backups: {e}")
return False
# Использование
cloud_backup = CloudBackup({
'access_key': 'YOUR_ACCESS_KEY',
'secret_key': 'YOUR_SECRET_KEY',
'region': 'us-east-1',
'bucket': 'your-backup-bucket'
})
# Загрузка бэкапа в S3
s3_key = f"bot_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.tar.gz"
if cloud_backup.upload_to_s3("/backups/bot_backup.tar.gz", s3_key):
print("Backup uploaded to S3 successfully")Интеграция с Google Cloud Storage
# gcs_backup.py
from google.cloud import storage
import os
from datetime import datetime
import logging
class GCSBackup:
def __init__(self, gcs_config):
self.gcs_config = gcs_config
self.client = storage.Client()
self.bucket = self.client.bucket(gcs_config['bucket'])
self.logger = logging.getLogger(__name__)
def upload_to_gcs(self, local_file_path, gcs_key):
"""Загрузка файла в Google Cloud Storage"""
try:
blob = self.bucket.blob(gcs_key)
blob.upload_from_filename(local_file_path)
self.logger.info(f"File uploaded to GCS: {gcs_key}")
return True
except Exception as e:
self.logger.error(f"Error uploading to GCS: {e}")
return False
def download_from_gcs(self, gcs_key, local_file_path):
"""Скачивание файла из Google Cloud Storage"""
try:
blob = self.bucket.blob(gcs_key)
blob.download_to_filename(local_file_path)
self.logger.info(f"File downloaded from GCS: {gcs_key}")
return True
except Exception as e:
self.logger.error(f"Error downloading from GCS: {e}")
return False
def set_lifecycle_policy(self, retention_days=30):
"""Установка политики жизненного цикла"""
try:
lifecycle_rule = {
"lifecycle": {
"rule": [
{
"action": {"type": "Delete"},
"condition": {"age": retention_days}
}
]
}
}
self.bucket.lifecycle_rules = lifecycle_rule
self.bucket.patch()
self.logger.info(f"Lifecycle policy set: {retention_days} days")
return True
except Exception as e:
self.logger.error(f"Error setting lifecycle policy: {e}")
return False
# Использование
gcs_backup = GCSBackup({
'bucket': 'your-backup-bucket'
})
# Загрузка бэкапа в GCS
gcs_key = f"bot_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.tar.gz"
if gcs_backup.upload_to_gcs("/backups/bot_backup.tar.gz", gcs_key):
print("Backup uploaded to GCS successfully")Восстановление данных
Скрипт восстановления
#!/bin/bash
# restore-backup.sh
# Конфигурация
BACKUP_DIR="/backups"
RESTORE_DIR="/tmp/restore"
DB_NAME="bot_database"
DB_USER="bot_user"
DB_PASS="bot_password"
# Функция логирования
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $BACKUP_DIR/restore.log
}
# Функция восстановления из архива
restore_from_archive() {
local backup_file=$1
local restore_path=$2
log "Восстановление из архива: $backup_file"
# Создание директории для восстановления
mkdir -p $restore_path
# Извлечение архива
tar -xzf "$backup_file" -C $restore_path
if [ $? -eq 0 ]; then
log "Архив успешно извлечен"
return 0
else
log "Ошибка извлечения архива"
return 1
fi
}
# Функция восстановления файлов
restore_files() {
local source_path=$1
local target_path=$2
log "Восстановление файлов из $source_path в $target_path"
# Остановка ботов
systemctl stop telegram-bot
systemctl stop discord-bot
systemctl stop vk-bot
# Создание бэкапа текущих файлов
log "Создание бэкапа текущих файлов"
cp -r $target_path "${target_path}_backup_$(date +%Y%m%d_%H%M%S)"
# Восстановление файлов
cp -r $source_path/* $target_path/
# Установка правильных прав
chown -R botuser:botuser $target_path
chmod -R 755 $target_path
log "Файлы восстановлены"
}
# Функция восстановления базы данных
restore_database() {
local db_backup_file=$1
log "Восстановление базы данных из $db_backup_file"
# Остановка сервисов
systemctl stop telegram-bot
systemctl stop discord-bot
systemctl stop vk-bot
# Создание бэкапа текущей базы данных
log "Создание бэкапа текущей базы данных"
pg_dump -h localhost -U $DB_USER -d $DB_NAME > "${DB_NAME}_backup_$(date +%Y%m%d_%H%M%S).sql"
# Восстановление базы данных
if [ -f "$db_backup_file" ]; then
if [[ "$db_backup_file" == *.gz ]]; then
gunzip -c "$db_backup_file" | psql -h localhost -U $DB_USER -d $DB_NAME
else
psql -h localhost -U $DB_USER -d $DB_NAME < "$db_backup_file"
fi
if [ $? -eq 0 ]; then
log "База данных восстановлена"
else
log "Ошибка восстановления базы данных"
return 1
fi
else
log "Файл бэкапа базы данных не найден: $db_backup_file"
return 1
fi
}
# Функция полного восстановления
full_restore() {
local backup_file=$1
log "=== Начало полного восстановления ==="
# Проверка существования файла бэкапа
if [ ! -f "$backup_file" ]; then
log "Ошибка: Файл бэкапа не найден: $backup_file"
exit 1
fi
# Восстановление из архива
if restore_from_archive "$backup_file" "$RESTORE_DIR"; then
# Поиск файлов бэкапа
backup_name=$(basename "$backup_file" .tar.gz)
extracted_path="$RESTORE_DIR/$backup_name"
# Восстановление файлов ботов
for bot_dir in telegram-bot discord-bot vk-bot; do
if [ -d "$extracted_path/$bot_dir" ]; then
restore_files "$extracted_path/$bot_dir" "/home/botuser/$bot_dir"
fi
done
# Восстановление базы данных
if [ -f "$extracted_path/database.sql" ]; then
restore_database "$extracted_path/database.sql"
fi
# Запуск сервисов
log "Запуск сервисов"
systemctl start telegram-bot
systemctl start discord-bot
systemctl start vk-bot
# Очистка временных файлов
rm -rf $RESTORE_DIR
log "=== Восстановление завершено ==="
else
log "Ошибка восстановления из архива"
exit 1
fi
}
# Основная функция
main() {
if [ $# -eq 0 ]; then
echo "Использование: $0 <backup_file>"
echo "Пример: $0 /backups/bot_backup_20231201_120000.tar.gz"
exit 1
fi
backup_file=$1
full_restore "$backup_file"
}
# Запуск
main "$@"Мониторинг и тестирование
Мониторинг бэкапов
# backup_monitor.py
import os
import time
import smtplib
from email.mime.text import MIMEText
from datetime import datetime, timedelta
import logging
class BackupMonitor:
def __init__(self, backup_dir, email_config):
self.backup_dir = backup_dir
self.email_config = email_config
self.logger = logging.getLogger(__name__)
def check_backup_freshness(self, max_age_hours=24):
"""Проверка свежести бэкапов"""
try:
backup_files = [f for f in os.listdir(self.backup_dir) if f.endswith('.tar.gz')]
if not backup_files:
self.send_alert("No backup files found")
return False
# Поиск самого свежего бэкапа
latest_backup = max(backup_files, key=lambda f: os.path.getmtime(os.path.join(self.backup_dir, f)))
latest_backup_path = os.path.join(self.backup_dir, latest_backup)
# Проверка возраста
backup_age = datetime.now() - datetime.fromtimestamp(os.path.getmtime(latest_backup_path))
if backup_age.total_seconds() > max_age_hours * 3600:
self.send_alert(f"Backup is too old: {latest_backup} (age: {backup_age})")
return False
self.logger.info(f"Latest backup is fresh: {latest_backup}")
return True
except Exception as e:
self.logger.error(f"Error checking backup freshness: {e}")
return False
def check_backup_integrity(self):
"""Проверка целостности бэкапов"""
try:
backup_files = [f for f in os.listdir(self.backup_dir) if f.endswith('.tar.gz')]
for backup_file in backup_files:
backup_path = os.path.join(self.backup_dir, backup_file)
# Проверка архива
if not self.verify_tar_archive(backup_path):
self.send_alert(f"Backup integrity check failed: {backup_file}")
return False
self.logger.info("All backups passed integrity check")
return True
except Exception as e:
self.logger.error(f"Error checking backup integrity: {e}")
return False
def verify_tar_archive(self, archive_path):
"""Проверка целостности tar архива"""
try:
import tarfile
with tarfile.open(archive_path, 'r:gz') as tar:
tar.getmembers()
return True
except Exception as e:
self.logger.error(f"Archive verification failed for {archive_path}: {e}")
return False
def send_alert(self, message):
"""Отправка уведомления"""
try:
msg = MIMEText(f"Backup Alert: {message}")
msg['Subject'] = 'Backup Alert'
msg['From'] = self.email_config['from']
msg['To'] = self.email_config['to']
with smtplib.SMTP(self.email_config['smtp_server'], self.email_config['smtp_port']) as server:
server.starttls()
server.login(self.email_config['username'], self.email_config['password'])
server.send_message(msg)
self.logger.info(f"Alert sent: {message}")
except Exception as e:
self.logger.error(f"Error sending alert: {e}")
def run_monitoring(self):
"""Запуск мониторинга"""
while True:
try:
# Проверка свежести
if not self.check_backup_freshness():
continue
# Проверка целостности
if not self.check_backup_integrity():
continue
self.logger.info("Backup monitoring check passed")
time.sleep(3600) # Проверка каждый час
except KeyboardInterrupt:
break
except Exception as e:
self.logger.error(f"Error in monitoring loop: {e}")
time.sleep(3600)
# Использование
monitor = BackupMonitor(
backup_dir="/backups",
email_config={
'smtp_server': 'smtp.gmail.com',
'smtp_port': 587,
'username': 'your_email@gmail.com',
'password': 'your_password',
'from': 'your_email@gmail.com',
'to': 'admin@yourdomain.com'
}
)
monitor.run_monitoring()Тестирование восстановления
#!/bin/bash
# test-restore.sh
# Конфигурация
TEST_DIR="/tmp/backup_test"
BACKUP_FILE="/backups/bot_backup_20231201_120000.tar.gz"
# Функция логирования
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a /var/log/backup_test.log
}
# Функция тестирования восстановления
test_restore() {
local backup_file=$1
log "=== Начало тестирования восстановления ==="
# Создание тестовой директории
mkdir -p $TEST_DIR
cd $TEST_DIR
# Извлечение архива
log "Извлечение архива: $backup_file"
tar -xzf "$backup_file"
if [ $? -eq 0 ]; then
log "Архив успешно извлечен"
# Проверка содержимого
log "Проверка содержимого архива"
find . -type f -name "*.py" | head -5
find . -type f -name "*.sql" | head -5
# Проверка базы данных
if [ -f "*/database.sql" ]; then
log "Файл базы данных найден"
# Проверка синтаксиса SQL
if head -10 */database.sql | grep -q "CREATE TABLE\|INSERT INTO"; then
log "SQL файл выглядит корректно"
else
log "Предупреждение: SQL файл может быть поврежден"
fi
else
log "Предупреждение: Файл базы данных не найден"
fi
log "Тестирование восстановления завершено успешно"
else
log "Ошибка извлечения архива"
return 1
fi
# Очистка
cd /
rm -rf $TEST_DIR
log "=== Тестирование восстановления завершено ==="
return 0
}
# Основная функция
main() {
if [ $# -eq 0 ]; then
echo "Использование: $0 <backup_file>"
echo "Пример: $0 /backups/bot_backup_20231201_120000.tar.gz"
exit 1
fi
backup_file=$1
if [ ! -f "$backup_file" ]; then
log "Ошибка: Файл бэкапа не найден: $backup_file"
exit 1
fi
test_restore "$backup_file"
}
# Запуск
main "$@"Аварийное восстановление
План аварийного восстановления
#!/bin/bash
# disaster-recovery.sh
# Конфигурация
BACKUP_SERVER="backup.yourdomain.com"
BACKUP_USER="backup_user"
BACKUP_DIR="/backups"
LOCAL_RESTORE_DIR="/tmp/disaster_recovery"
# Функция логирования
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a /var/log/disaster_recovery.log
}
# Функция скачивания бэкапа
download_backup() {
local backup_file=$1
local local_path=$2
log "Скачивание бэкапа: $backup_file"
# Скачивание через SCP
scp "$BACKUP_USER@$BACKUP_SERVER:$BACKUP_DIR/$backup_file" "$local_path"
if [ $? -eq 0 ]; then
log "Бэкап успешно скачан"
return 0
else
log "Ошибка скачивания бэкапа"
return 1
fi
}
# Функция быстрого восстановления
quick_recovery() {
local backup_file=$1
log "=== Начало быстрого восстановления ==="
# Скачивание бэкапа
local_backup_path="$LOCAL_RESTORE_DIR/$(basename $backup_file)"
if ! download_backup "$backup_file" "$local_backup_path"; then
return 1
fi
# Восстановление критически важных сервисов
log "Восстановление критически важных сервисов"
# Остановка всех сервисов
systemctl stop telegram-bot
systemctl stop discord-bot
systemctl stop vk-bot
systemctl stop nginx
# Извлечение архива
cd $LOCAL_RESTORE_DIR
tar -xzf "$(basename $backup_file)"
# Восстановление конфигурации Nginx
if [ -f "*/nginx.conf" ]; then
cp "*/nginx.conf" /etc/nginx/nginx.conf
systemctl start nginx
log "Nginx восстановлен"
fi
# Восстановление базы данных
if [ -f "*/database.sql" ]; then
# Создание новой базы данных
createdb -U postgres bot_database_recovery
# Восстановление данных
psql -U postgres -d bot_database_recovery < "*/database.sql"
# Переключение на восстановленную базу данных
systemctl stop postgresql
# Здесь должна быть логика переключения на восстановленную базу данных
systemctl start postgresql
log "База данных восстановлена"
fi
# Восстановление файлов ботов
for bot_dir in telegram-bot discord-bot vk-bot; do
if [ -d "*/$bot_dir" ]; then
cp -r "*/$bot_dir" "/home/botuser/"
chown -R botuser:botuser "/home/botuser/$bot_dir"
systemctl start "$bot_dir"
log "$bot_dir восстановлен"
fi
done
# Очистка
rm -rf $LOCAL_RESTORE_DIR
log "=== Быстрое восстановление завершено ==="
return 0
}
# Функция полного восстановления
full_recovery() {
local backup_file=$1
log "=== Начало полного восстановления ==="
# Скачивание бэкапа
local_backup_path="$LOCAL_RESTORE_DIR/$(basename $backup_file)"
if ! download_backup "$backup_file" "$local_backup_path"; then
return 1
fi
# Полное восстановление системы
# Здесь должна быть логика полного восстановления системы
log "=== Полное восстановление завершено ==="
return 0
}
# Основная функция
main() {
if [ $# -lt 2 ]; then
echo "Использование: $0 <recovery_type> <backup_file>"
echo "Типы восстановления: quick, full"
echo "Пример: $0 quick bot_backup_20231201_120000.tar.gz"
exit 1
fi
recovery_type=$1
backup_file=$2
# Создание директории для восстановления
mkdir -p $LOCAL_RESTORE_DIR
case $recovery_type in
"quick")
quick_recovery "$backup_file"
;;
"full")
full_recovery "$backup_file"
;;
*)
echo "Неизвестный тип восстановления: $recovery_type"
exit 1
;;
esac
}
# Запуск
main "$@"Заключение
В этой статье мы рассмотрели стратегии резервного копирования ботов:- ✅ Стратегии резервного копирования и планирование
- ✅ Автоматические бэкапы и cron настройка
- ✅ Резервное копирование различных типов баз данных
- ✅ Интеграция с облачными хранилищами
- ✅ Восстановление данных и тестирование
- ✅ Мониторинг и проверка целостности
- ✅ План аварийного восстановления
Полезные ссылки
628 просмотров
45 лайков
0 комментариев
Комментарии (0)
Пока нет комментариев. Будьте первым!