Это старая версия документа!


Скрипт резервного копирования PGVector

Скрипт автоматизированного резервного копирования для контейнеров PGVector (PostgreSQL с расширением vector) и pgAdmin. Создает полные бекапы включающие SQL дампы и архивы данных.

Возможности:

  • Создание SQL дампов базы данных
  • Архивирование папок с данными PostgreSQL и pgAdmin
  • Автоматическая очистка старых бекапов
  • Подробное логирование операций
  • Проверка работоспособности сервисов
  • Уведомления в Telegram (опционально)

<note tip> Скрипт безопасно останавливает контейнеры для создания консистентного бекапа и автоматически запускает их обратно. </note>

  • Docker и Docker Compose установлены
  • Контейнеры PGVector запущены из директории /opt/pgvector
  • Права root или sudo для выполнения операций
sudo mkdir -p /opt/scripts
sudo mkdir -p /opt/backups/pgvector
sudo nano /opt/scripts/pgvector-backup.sh

Скопируйте следующий код в файл:

/opt/scripts/pgvector-backup.sh
#!/bin/bash
# Скрипт резервного копирования PGVector
# Запуск: /opt/scripts/pgvector-backup.sh
 
# Настройки
COMPOSE_FILE="/opt/pgvector/docker-compose.yml"
PGVECTOR_DIR="/opt/pgvector"
BACKUP_DIR="/opt/backups/pgvector"
DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_NAME="pgvector_backup_${DATE}"
RETENTION_DAYS=10  # Храним бекапы 10 дней
 
# Настройки базы данных
DB_NAME="postgres"
DB_USER="postgres"
DB_PASSWORD="YOUR_POSTGRES_PASSWORD"  # Замените на ваш пароль из docker-compose.yml
DB_CONTAINER="pgvector_postgres"
 
# Логирование
LOG_FILE="${BACKUP_DIR}/backup.log"
 
# Функция логирования
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
 
# Создаем директорию для бекапов если не существует
mkdir -p "$BACKUP_DIR"
 
log "=== Начало резервного копирования PGVector ==="
 
# Проверяем что compose файл существует
if [ ! -f "$COMPOSE_FILE" ]; then
    log "ОШИБКА: Файл $COMPOSE_FILE не найден!"
    exit 1
fi
 
# Переходим в директорию с PGVector
cd "$PGVECTOR_DIR" || {
    log "ОШИБКА: Не удалось перейти в директорию $PGVECTOR_DIR"
    exit 1
}
 
# Проверяем что контейнеры запущены
if ! docker-compose ps | grep -q "Up"; then
    log "ПРЕДУПРЕЖДЕНИЕ: Не все контейнеры запущены"
fi
 
# Создаем дамп базы данных
log "Создаем дамп базы данных..."
DB_DUMP_FILE="${BACKUP_DIR}/${BACKUP_NAME}_database.sql"
docker exec -t "$DB_CONTAINER" pg_dump -U "$DB_USER" -d "$DB_NAME" > "$DB_DUMP_FILE"
 
if [ $? -eq 0 ]; then
    log "Дамп базы данных создан: $DB_DUMP_FILE"
    DB_SIZE=$(du -h "$DB_DUMP_FILE" | cut -f1)
    log "Размер дампа базы данных: $DB_SIZE"
else
    log "ОШИБКА: Не удалось создать дамп базы данных"
    exit 1
fi
 
# Создаем дамп всех баз данных (включая системные)
log "Создаем полный дамп всех баз данных..."
DB_FULL_DUMP_FILE="${BACKUP_DIR}/${BACKUP_NAME}_all_databases.sql"
docker exec -t "$DB_CONTAINER" pg_dumpall -U "$DB_USER" > "$DB_FULL_DUMP_FILE"
 
if [ $? -eq 0 ]; then
    log "Полный дамп баз данных создан: $DB_FULL_DUMP_FILE"
    DB_FULL_SIZE=$(du -h "$DB_FULL_DUMP_FILE" | cut -f1)
    log "Размер полного дампа: $DB_FULL_SIZE"
else
    log "ПРЕДУПРЕЖДЕНИЕ: Не удалось создать полный дамп баз данных"
fi
 
# Останавливаем контейнеры для консистентного бекапа файлов
log "Останавливаем контейнеры PGVector..."
docker-compose -f "$COMPOSE_FILE" down
 
if [ $? -eq 0 ]; then
    log "Контейнеры успешно остановлены"
else
    log "ОШИБКА: Не удалось остановить контейнеры"
    exit 1
fi
 
# Ждем пару секунд для полной остановки
sleep 5
 
# Создаем архив с данными
log "Создаем архив данных..."
BACKUP_ARCHIVE="${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"
tar -czf "$BACKUP_ARCHIVE" \
    --exclude='*.log' \
    --exclude='**/lost+found' \
    --exclude='tmp/' \
    --exclude='log/' \
    postgres_data/ \
    pgadmin_data/ \
    docker-compose.yml
 
if [ $? -eq 0 ]; then
    log "Архив создан: $BACKUP_ARCHIVE"
 
    # Получаем размер архива
    ARCHIVE_SIZE=$(du -h "$BACKUP_ARCHIVE" | cut -f1)
    log "Размер архива: $ARCHIVE_SIZE"
else
    log "ОШИБКА: Не удалось создать архив"
 
    # Пытаемся запустить контейнеры даже при ошибке
    log "Запускаем контейнеры после ошибки..."
    docker-compose -f "$COMPOSE_FILE" up -d
    exit 1
fi
 
# Запускаем контейнеры обратно
log "Запускаем контейнеры PGVector..."
docker-compose -f "$COMPOSE_FILE" up -d
 
if [ $? -eq 0 ]; then
    log "Контейнеры успешно запущены"
else
    log "ОШИБКА: Не удалось запустить контейнеры"
    exit 1
fi
 
# Ждем запуска сервисов
log "Ожидаем запуска сервисов..."
sleep 30
 
# Проверяем что все контейнеры работают
log "Проверяем статус контейнеров..."
if docker-compose -f "$COMPOSE_FILE" ps | grep -q "Up"; then
    log "Контейнеры работают корректно"
else
    log "ПРЕДУПРЕЖДЕНИЕ: Некоторые контейнеры могут работать некорректно"
fi
 
# Проверяем подключение к базе данных
log "Проверяем подключение к базе данных..."
if docker exec "$DB_CONTAINER" pg_isready -U "$DB_USER" >/dev/null 2>&1; then
    log "База данных доступна"
else
    log "ПРЕДУПРЕЖДЕНИЕ: База данных может быть недоступна"
fi
 
# Проверяем что расширение pgvector доступно
log "Проверяем расширение pgvector..."
if docker exec "$DB_CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" -c "SELECT extname FROM pg_extension WHERE extname='vector';" | grep -q "vector"; then
    log "Расширение pgvector активно"
else
    log "ПРЕДУПРЕЖДЕНИЕ: Расширение pgvector может быть неактивно"
fi
 
# Создаем итоговый архив с дампами базы данных
log "Создаем итоговый архив с дампами базы данных..."
FINAL_BACKUP="${BACKUP_DIR}/${BACKUP_NAME}_complete.tar.gz"
 
# Добавляем в архив файлы данных и дампы
tar -czf "$FINAL_BACKUP" -C "$BACKUP_DIR" \
    "${BACKUP_NAME}.tar.gz" \
    "${BACKUP_NAME}_database.sql" \
    "${BACKUP_NAME}_all_databases.sql"
 
if [ $? -eq 0 ]; then
    log "Итоговый архив создан: $FINAL_BACKUP"
 
    # Получаем размер итогового архива
    BACKUP_SIZE=$(du -h "$FINAL_BACKUP" | cut -f1)
    log "Размер итогового архива: $BACKUP_SIZE"
 
    # Удаляем промежуточные файлы
    rm -f "$BACKUP_ARCHIVE" "$DB_DUMP_FILE" "$DB_FULL_DUMP_FILE"
    log "Промежуточные файлы удалены"
else
    log "ОШИБКА: Не удалось создать итоговый архив"
fi
 
# Удаляем старые бекапы
log "Удаляем бекапы старше $RETENTION_DAYS дней..."
find "$BACKUP_DIR" -name "pgvector_backup_*_complete.tar.gz" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "pgvector_backup_*.tar.gz" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "pgvector_backup_*_database.sql" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "pgvector_backup_*_all_databases.sql" -mtime +$RETENTION_DAYS -delete
 
# Показываем статистику бекапов
BACKUP_COUNT=$(ls -1 "${BACKUP_DIR}"/pgvector_backup_*_complete.tar.gz 2>/dev/null | wc -l)
log "Общее количество полных бекапов: $BACKUP_COUNT"
 
# Показываем общий размер всех бекапов
TOTAL_SIZE=$(du -sh "$BACKUP_DIR" | cut -f1)
log "Общий размер директории бекапов: $TOTAL_SIZE"
 
log "=== Резервное копирование завершено успешно ==="
 
# Отправляем уведомление в Telegram (раскомментируйте и укажите свои данные)
# curl -s -X POST "https://api.telegram.org/botYOUR_BOT_TOKEN/sendMessage" \
#      -d chat_id="YOUR_CHAT_ID" \
#      -d text="✅ PGVector backup completed: $BACKUP_NAME ($FINAL_SIZE)"
 
exit 0
sudo chmod +x /opt/scripts/pgvector-backup.sh
sudo chown root:root /opt/scripts/pgvector-backup.sh
sudo chown -R $USER:$USER /opt/backups/pgvector

Отредактируйте переменные в начале скрипта под ваши нужды:

/opt/scripts/pgvector-backup.sh
# Настройки путей
COMPOSE_FILE="/opt/pgvector/docker-compose.yml"
PGVECTOR_DIR="/opt/pgvector"
BACKUP_DIR="/opt/backups/pgvector"
 
# Настройки хранения
RETENTION_DAYS=10  # Количество дней хранения бекапов
 
# Настройки базы данных
DB_NAME="postgres"
DB_USER="postgres"
DB_PASSWORD="YOUR_POSTGRES_PASSWORD"  # Ваш пароль из docker-compose.yml
DB_CONTAINER="pgvector_postgres"

<note warning> Убедитесь, что пароль базы данных в скрипте соответствует паролю в docker-compose.yml </note>

Раскомментируйте и настройте строки в конце скрипта:

curl -s -X POST "https://api.telegram.org/botYOUR_BOT_TOKEN/sendMessage" \
     -d chat_id="YOUR_CHAT_ID" \
     -d text="✅ PGVector backup completed: $BACKUP_NAME ($FINAL_SIZE)"
# Запуск с правами root
sudo /opt/scripts/pgvector-backup.sh
 
# Запуск с отображением вывода
sudo /opt/scripts/pgvector-backup.sh | tee /tmp/backup.log
# Просмотр последних логов
tail -f /opt/backups/pgvector/backup.log
 
# Просмотр всех логов
cat /opt/backups/pgvector/backup.log
sudo crontab -e

Добавьте одну из следующих строк:

# Ежедневно в 2:00 ночи
0 2 * * * /opt/scripts/pgvector-backup.sh >/dev/null 2>&1

# Еженедельно по воскресеньям в 3:00
0 3 * * 0 /opt/scripts/pgvector-backup.sh >/dev/null 2>&1

# Ежедневно в 2:00 с логированием в syslog
0 2 * * * /opt/scripts/pgvector-backup.sh 2>&1 | logger -t pgvector-backup
# Проверка статуса cron
sudo systemctl status cron
 
# Просмотр логов cron
sudo grep pgvector /var/log/syslog

После выполнения скрипта в /opt/backups/pgvector будут созданы:

Файл Описание
pgvector_backup_YYYYMMDD_HHMMSS_complete.tar.gz Итоговый архив со всеми данными
backup.log Лог-файл операций

Содержимое итогового архива:

  • SQL дамп основной базы данных
  • Полный SQL дамп всех баз данных
  • Архив папок postgres_data и pgadmin_data
  • Файл docker-compose.yml
# 1. Остановите контейнеры
cd /opt/pgvector
sudo docker-compose down
 
# 2. Создайте резервную копию текущих данных
sudo mv postgres_data postgres_data.old
sudo mv pgadmin_data pgadmin_data.old
 
# 3. Извлеките бекап
cd /opt/backups/pgvector
sudo tar -xzf pgvector_backup_YYYYMMDD_HHMMSS_complete.tar.gz
 
# 4. Извлеките данные из архива
sudo tar -xzf pgvector_backup_YYYYMMDD_HHMMSS.tar.gz -C /opt/pgvector
 
# 5. Запустите контейнеры
cd /opt/pgvector
sudo docker-compose up -d
# 1. Извлеките SQL дамп
cd /opt/backups/pgvector
tar -xzf pgvector_backup_YYYYMMDD_HHMMSS_complete.tar.gz
 
# 2. Восстановите базу данных
docker exec -i pgvector_postgres psql -U postgres -d postgres < pgvector_backup_YYYYMMDD_HHMMSS_database.sql
 
# Или восстановите все базы данных
docker exec -i pgvector_postgres psql -U postgres < pgvector_backup_YYYYMMDD_HHMMSS_all_databases.sql
# Размер всех бекапов
du -sh /opt/backups/pgvector
 
# Список всех бекапов с размерами
ls -lah /opt/backups/pgvector/*.tar.gz
# Удалить бекапы старше 30 дней
find /opt/backups/pgvector -name "pgvector_backup_*" -mtime +30 -delete
# Проверка целостности архива
tar -tzf /opt/backups/pgvector/pgvector_backup_YYYYMMDD_HHMMSS_complete.tar.gz
 
# Проверка SQL дампа
head -20 pgvector_backup_YYYYMMDD_HHMMSS_database.sql

Ошибка: «Файл docker-compose.yml не найден»

# Проверьте путь к файлу
ls -la /opt/pgvector/docker-compose.yml
# Отредактируйте переменную COMPOSE_FILE в скрипте

Ошибка: «Контейнер не найден»

# Проверьте имена контейнеров
docker ps -a
# Обновите переменную DB_CONTAINER в скрипте

Ошибка подключения к базе данных

# Проверьте статус контейнера
docker exec pgvector_postgres pg_isready -U postgres
 
# Проверьте пароль
docker exec -it pgvector_postgres psql -U postgres
# Запуск с подробными логами
sudo bash -x /opt/scripts/pgvector-backup.sh
 
# Проверка логов Docker
docker logs pgvector_postgres
docker logs pgvector_pgadmin

<note important> Рекомендации по безопасности:

  • Храните бекапы на отдельном диске или удаленном сервере
  • Регулярно проверяйте целостность бекапов
  • Ограничьте права доступа к директории с бекапами
  • Зашифруйте бекапы при передаче по сети

</note>

# Ограничить доступ к директории бекапов
sudo chmod 750 /opt/backups/pgvector
sudo chown root:backup /opt/backups/pgvector
 
# Ограничить доступ к скрипту
sudo chmod 750 /opt/scripts/pgvector-backup.sh

Добавьте в конец скрипта:

# Отправка через rsync
rsync -avz "$FINAL_BACKUP" user@remote-server:/backup/pgvector/
 
# Отправка через scp
scp "$FINAL_BACKUP" user@remote-server:/backup/pgvector/
# Отправка метрик в InfluxDB
curl -X POST 'http://influxdb:8086/write?db=monitoring' \
--data-binary "pgvector_backup,host=$(hostname) size=${FINAL_SIZE_BYTES} $(date +%s)000000000"

Последнее обновление: $(date)

  • vm/pgvector/03-backup.1756457533.txt.gz
  • Последнее изменение: 2025/08/29 08:52
  • admin