B23: скрипты бэкапа/восстановления прикладного дампа

- backup-app.sh: pg_dump 16 (--exclude planet_osm_*), .env+compose в tar,
  verify через pg_restore --list, чистка >14 дней
- restore-app.sh: pg_restore 16 --clean --if-exists + TOC без EXTENSION
- ГРАБЛИ pg_wrapper PG18 в контейнере postgres:16: архив версии 1.16
  не читается pg_restore 16 (unsupported version) + SET transaction_timeout
  нет в PG16 — только /usr/lib/postgresql/16/bin/pg_*
This commit is contained in:
2026-09-25 10:07:37 +03:00
parent c6be70ce36
commit 9b6659a85a
2 changed files with 81 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
#!/bin/bash
# B23: ежедневный прикладной бэкап ВЕКТОРа (без planet_osm_*; OSM восстанавливается b16-import.sh).
#
# ВАЖНО: дампить ТОЛЬКО /usr/lib/postgresql/16/bin/pg_dump. pg_wrapper в контейнере
# postgres:16 указывает на клиент PG18: pg_dump 18 создаёт архив версии 1.16,
# который pg_restore 16 не читает ("unsupported version"), и пишет
# "SET transaction_timeout", отсутствующий в PG16-сервере.
# См. setup грабли: scripts/restore-app.sh.
set -u
DATE=$(date +%F)
LOG=/var/log/vector-backup.log
KEEP_DAYS=14
PG16=/usr/lib/postgresql/16/bin
log() { echo "[$(date '+%F %T')] $*" >> "$LOG"; }
log "backup start $DATE"
# 1. Дамп прикладных таблиц (маленький, ~80 КБ)
docker exec vector-postgres "$PG16/pg_dump" -U postgres -d vector_mchs \
--exclude-table='planet_osm_*' -F c -f "/tmp/vector_app_${DATE}.dump" \
|| { log "PG_DUMP FAILED"; exit 1; }
# 2. Выгрузка из контейнера
mkdir -p /root/backups
docker cp "vector-postgres:/tmp/vector_app_${DATE}.dump" "/root/backups/" \
|| { log "DOCKER_CP FAILED"; exit 1; }
docker exec vector-postgres rm -f "/tmp/vector_app_${DATE}.dump"
# 3. .env и compose-конфигурация (JWT_SECRET, пароль БД, CONTOUR_TOKEN)
tar czf "/root/backups/vector_env_${DATE}.tar.gz" -C /root/vector .env docker-compose.yml 2>/dev/null
chmod 600 /root/backups/vector_env_*.tar.gz
# 4. Проверка дампа: pg_restore 16 читает оглавление (формат/целостность)
docker cp "/root/backups/vector_app_${DATE}.dump" vector-postgres:/tmp/verify.dump
docker exec vector-postgres "$PG16/pg_restore" --list /tmp/verify.dump > /dev/null 2>&1 \
|| { log "DUMP VERIFY FAILED"; exit 1; }
docker exec vector-postgres rm -f /tmp/verify.dump
# 5. Чистка старше KEEP_DAYS
find /root/backups -name "vector_app_*.dump" -mtime +$KEEP_DAYS -delete
find /root/backups -name "vector_env_*.tar.gz" -mtime +$KEEP_DAYS -delete
log "backup ok: $(du -h "/root/backups/vector_app_${DATE}.dump" | cut -f1)"
+37
View File
@@ -0,0 +1,37 @@
#!/bin/bash
# B23: восстановление прикладного дампа ВЕКТОРа в живую БД.
#
# Грабли (реальный прогон 2026-09):
# 1. pg_dump/pg_restore в контейнере postgres:16 — pg_wrapper ведёт на клиент PG18:
# pg_restore 18 создаёт архив версии 1.16, который pg_restore 16 НЕ читает
# ("unsupported version"), и пишет "SET transaction_timeout", отсутствующий
# в PG16-сервере. Лечение: ТОЛЬКО /usr/lib/postgresql/16/bin/pg_*.
# 2. --clean дропает postgis → падение на зависимостях planet_osm_*.
# EXTENSION-строки фильтруются из TOC (postgis стоит, OSM-данных в дампе нет).
# Использование: restore-app.sh /root/backups/vector_app_2026-09-25.dump
set -eu
LOG=/var/log/vector-restore.log
PG16=/usr/lib/postgresql/16/bin
log() { echo "[$(date '+%F %T')] $*" >> "$LOG"; }
if [ $# -lt 1 ] || [ ! -f "$1" ]; then
echo "usage: restore-app.sh <dump-file>" >&2
exit 1
fi
log "restore start from $1"
docker cp "$1" vector-postgres:/tmp/restore.dump
# TOC без EXTENSION postgis (уже установлен; дамп OSM-таблиц не содержит)
docker exec vector-postgres "$PG16/pg_restore" --list /tmp/restore.dump | grep -v EXTENSION > /tmp/restore.toc
if docker exec vector-postgres "$PG16/pg_restore" -U postgres -d vector_mchs \
--clean --if-exists --no-owner --use-list=/tmp/restore.toc /tmp/restore.dump; then
log "restore ok"
else
log "RESTORE FAILED"
exit 1
fi
docker exec vector-postgres rm -f /tmp/restore.dump /tmp/restore.toc
log "done"