#!/bin/bash # ============================================================================== # PostgreSQLRestore — obnovení PostgreSQL 18 ze zálohy # ============================================================================== # # CO DĚLÁ: # Obnoví celý PostgreSQL 18 server z pg_dumpall zálohy. # Pokud není zadán konkrétní adresář, automaticky najde nejnovější zálohu. # # POUŽITÍ: # bash postgresqlrestore_from_backup.sh [cesta_k_záloze] # # Bez argumentu — použije nejnovější zálohu: # bash postgresqlrestore_from_backup.sh # # S konkrétním adresářem: # bash postgresqlrestore_from_backup.sh /mnt/user/Backup/Critical/PostgreSQLBackup/tower/2026-05-23_0440 # # TECHNICKÉ DETAILY: # - gunzip -c: dekomprimuje na stdout (nezahazuje archiv) # - pipe → docker exec -i psql: stream SQL příkazů do PostgreSQL # - --dbname=postgres: psql se musí připojit k existující DB (postgres je vždy) # - --clean + --if-exists v dumpu: DROP objekty před jejich vytvoření # - ${PIPESTATUS[1]}: exit kód psql (ne gunzip) # # POZOR: # Restore přepíše všechna stávající data! Spouštět vědomě, ne automaticky. # Chybové hlášky jako "role already exists" jsou normální — dump je idempotentní. # ============================================================================== set -x # ============================================================================== # KONFIGURACE # ============================================================================== CONTAINER_NAME="postgresql18" PG_HOST="localhost" PG_PORT="5432" PG_USER="vladimir.buzalka" export PGPASSWORD="Vlado7309208104++" # Volitelný argument — konkrétní adresář zálohy. # Pokud není zadán, skript sám najde nejnovější. BACKUP_DIR="$1" BASE_PATH="/mnt/user/Backup/Critical/PostgreSQLBackup/tower" # ============================================================================== # NALEZENÍ ZÁLOHY # ============================================================================== if [ -z "$BACKUP_DIR" ]; then echo "No backup path specified - using latest available backup" # ls -td: seřadit adresáře dle mtime, nejnovější první # head -1: vzít jen nejnovější BACKUP_DIR=$(ls -td "$BASE_PATH"/*/ 2>/dev/null | head -1) if [ -z "$BACKUP_DIR" ]; then echo "ERROR: No backups found in $BASE_PATH" exit 1 fi fi if [ ! -d "$BACKUP_DIR" ]; then echo "ERROR: Backup directory does not exist: $BACKUP_DIR" exit 1 fi BACKUP_FILE="$BACKUP_DIR/all_databases.sql.gz" if [ ! -f "$BACKUP_FILE" ]; then echo "ERROR: Backup file not found: $BACKUP_FILE" exit 1 fi echo "Starting PostgreSQL restore from: $BACKUP_FILE" echo "Backup date: $(stat -c %y "$BACKUP_FILE" | cut -d' ' -f1-2)" echo "Backup size: $(du -h "$BACKUP_FILE" | cut -f1)" START_TS=$(date '+%Y-%m-%d %H:%M:%S') ERR_FILE="$BACKUP_DIR/all_databases.restore.err" # ============================================================================== # RESTORE # gunzip -c: dekomprimuje all_databases.sql.gz na stdout (soubor zůstane) # pipe → docker exec -i psql: SQL streamed přímo do PostgreSQL # -i: nutné pro stdin stream (bez -i by psql nedostával vstup) # --dbname=postgres: psql se musí připojit k nějaké DB — postgres vždy existuje # Záloha obsahuje příkazy pro všechny DB, role a grants — psql je postupně vykoná. # 2> "$ERR_FILE": stderr psql (chyby, warnings) — "role already exists" je normální # ============================================================================== echo "Restoring all databases to PostgreSQL..." gunzip -c "$BACKUP_FILE" \ | docker exec -i \ -e PGPASSWORD="$PGPASSWORD" \ "$CONTAINER_NAME" \ psql \ --host="$PG_HOST" \ --port="$PG_PORT" \ --username="$PG_USER" \ --dbname="postgres" \ 2> "$ERR_FILE" # PIPESTATUS[1] = exit kód docker exec / psql (index 1 = druhý prvek pipe) RESTORE_EXIT=${PIPESTATUS[1]} # ============================================================================== # VALIDACE # ============================================================================== if [ $RESTORE_EXIT -eq 0 ]; then echo "SUCCESS: All databases restored successfully" rm -f "$ERR_FILE" else echo "ERROR: Restore failed" echo "Exit code: $RESTORE_EXIT" echo "Error output:" [ -s "$ERR_FILE" ] && cat "$ERR_FILE" || echo " (no stderr output)" fi echo "------------------------------------------" echo "Restore task completed at $(date)" echo "Started at: $START_TS" set +x