МихаНическая Wiki!

Скрипт архивирования всех баз PostgreSQL на Linux (Версия 2.0).

Экспорт в PDF Преобразовать страницу в формат Open Document

Дата создания: 2026/07/01 08:43 (C) mihanik

Дано

  • Операционная система Linux с установленным PostgreSQL.
  • В СУБД создано несколько баз.
  • Имеется текстовый файл со списком баз, которые нужно архивировать.

Надо

  • Создать архивную копию баз из списка.
  • Бекап каждой базы должен храниться в отдельном архивном файле.
  • Во время архивации старые архивные копии должны перезаписываться.

Решение

Предыдущая версия скрипта расположена тут: Скрипт архивирования всех баз postgresql на linux

Исходный скрипт решал задачу, но был уязвим в нескольких местах.

Вот что было улучшено по категориям:

🛡️ Надёжность и защита данных

Было Стало Зачем
`rm -f $BackupDir/$dbname.sql.gz` перед созданиемЗапись в `.tmp` + `mv`Если бэкап упадёт, старый архив не будет потерян
Нет проверки результата `pg_dump``if pg_dump …; then … else … fi`Ошибки фиксируются, битые файлы удаляются
Нет ротации`find … -mtime +7 -delete`Диск не переполнится старыми архивами
Ротация (закомментирована, включается при необходимости)

🔒 Безопасность

Было Стало Зачем
`$BackupDir/$dbname.sql.gz` без кавычек`«$BackupDir/${dbname}.dump»`Защита от имён с пробелами
Парсинг через `tail|head|egrep`SQL-фильтр `WHERE datistemplate = false`Не зависит от формата вывода `psql`

📋 Функциональность

Было Стало Зачем
Бэкап всех БД кроме шаблоновСписок из файла `/opt/scripts/pg_backup_list.lst`Можно бэкапить только нужные БД, игнорировать комментарии
Plain SQL + `gzip`Кастомный формат `-Fc -Z 6`Быстрее, компактнее, можно восстанавливать отдельные таблицы
Нет отчётаСчётчики `total/success/failed`Видно результат выполнения
Код возврата всегда 0`exit 1` при ошибкахМониторинг (Zabbix, Prometheus) замечает сбои

📝 Удобство эксплуатации

Было Стало Зачем
`echo «Архив создан»``log()` с временными метками в файл и консольЕсть история в `/var/log/pg_backup.log`
Нет обработки peer-ошибок`-h localhost` в командахРаботает из-под любого пользователя ОС
Нет создания директории`mkdir -p «$BackupDir»`Скрипт не падает, если папка ещё не создана
Нет проверки списка БДПроверка существования `LIST_FILE`Ясная ошибка вместо молчаливого провала

🎯 Ключевые архитектурные изменения

1. Формат бэкапа

Было: pg_dump | gzip → .sql.gz
Стало: pg_dump -Fc -Z 6 → .dump

Это даёт:

  • Встроенное сжатие (не нужен gzip)
  • Возможность параллельного восстановления (pg_restore -j 4)
  • Возможность восстановить одну таблицу из дампа: pg_restore -t users …
  • Меньше нагрузка на CPU при дампе

2. Список баз

Было: Автоматический, все БД кроме шаблонов
Стало: Управляемый файл /opt/scripts/pg_backup_list.lst с комментариями

3. Аутентификация

  • Было: Подключение через unix-сокет → ошибка Peer authentication failed
  • Стало: -h localhost → TCP-подключение с проверкой пароля

Файл со списком баз

Создайте файл со списком баз для бэкапа: /opt/scripts/pg_backup_list.lst

pg_backup_list.lst
# Список баз для бэкапа
my_db1
my_db2
# analytics - временно отключена

Сам скрипт

pg_backup.sh
#!/bin/bash
 
# === Настройки ===
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
 
BackupDir="/mnt/backups/pgsql"
LIST_FILE="/opt/scripts/pg_backup_list.lst"
LOG_FILE="/var/log/pg_backup.log"
 
# Уровень сжатия кастомного формата (0-9, по умолчанию 6)
 
DUMP_COMPRESSION=6
 
# === Функции ===
 
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
 
# === Проверки ===
 
mkdir -p "$BackupDir" || { log "ОШИБКА: не удалось создать $BackupDir"; exit 1; }
 
if [ ! -f "$LIST_FILE" ]; then
    log "ОШИБКА: файл со списком баз $LIST_FILE не найден."
    exit 1
fi
 
# === Аутентификация ===
# Рекомендуется использовать ~/.pgpass вместо PGPASSWORD
 
export PGPASSWORD="123456"
 
log "=== Начало процесса бэкапа ==="
 
# === Счётчики для отчёта ===
 
total=0
success=0
failed=0
 
# === Основной цикл ===
 
while IFS= read -r dbname || [ -n "$dbname" ]; do
    # Убираем пробелы по краям
    dbname="$(echo "$dbname" | xargs)"
 
    # Пропускаем пустые строки и комментарии
    [[ -z "$dbname" || "$dbname" =~ ^[[:space:]]*# ]] && continue
 
    total=$((total + 1))
    log "[$total] Обработка базы: $dbname"
 
    temp_file="$BackupDir/${dbname}.dump.tmp"
    final_file="$BackupDir/${dbname}.dump"
 
    # -Fc  — кастомный формат (сжатый, бинарный)
    # -Z   — уровень сжатия (0-9)
    if pg_dump  -h localhost -U postgres -Fc -Z "$DUMP_COMPRESSION" "$dbname" > "$temp_file"; then
        mv "$temp_file" "$final_file"
        log "Успешно создан архив: $final_file"
        success=$((success + 1))
    else
        log "ОШИБКА при создании архива $dbname! Старый бэкап сохранен."
        rm -f "$temp_file"
        failed=$((failed + 1))
    fi
done < "$LIST_FILE"
 
# === Ротация: удаляем бэкапы старше 7 дней ===
# Закомментирована
 
#find "$BackupDir" -name "*.dump" -type f -mtime +7 -delete
#log "Ротация завершена: удалены файлы старше 7 дней."
 
# === Итог ===
 
unset PGPASSWORD
log "=== Завершение: всего=$total успешно=$success ошибок=$failed ==="
 
if [ "$failed" -gt 0 ]; then
    exit 1
fi

Источники

Наверх

В моей WIKI постоянно ведётся какая-то работа со статьями.
Если у вас возникли вопросы или замечания,
можете их отправлять на почту support@mihanik.net
Только авторизованные участники могут оставлять комментарии.
субд/postgresql/скрипт_архивирования_всех_баз_postgresql_на_linux_ver-2.0.txt · Последнее изменение: 2026/07/01 09:38 — mihanik
Яндекс.Метрика