#!/bin/bash # ============================================================================= # restore_all.sh # Przywracanie wszystkich baz PostgreSQL z katalogu backupu # wykonanego przez postgres_backup.sh # ============================================================================= CREDENTIALS_FILE="/usr/local/directadmin/conf/postgresql.conf" # Kolory tylko na terminalu if [[ -t 1 ]]; then RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' BOLD='\033[1m'; CYAN='\033[0;36m'; NC='\033[0m' else RED=''; GREEN=''; YELLOW=''; BOLD=''; CYAN=''; NC='' fi ok() { echo -e "${GREEN}[OK]${NC} $*"; } info() { echo -e " $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } die() { echo -e "${RED}[BŁĄD]${NC} $*" >&2; exit 1; } sekcja() { echo -e "\n${BOLD}${CYAN}--- $* ---${NC}\n"; } # --------------------------------------------------------------------------- # Sposób użycia # --------------------------------------------------------------------------- usage() { cat < [--restore-users] Opis: Przywraca wszystkie bazy danych z podanego katalogu backupu. Pliki w katalogu powinny być wykonane przez postgres_backup.sh. Flagi: --restore-users Przed przywracaniem baz odtworzy użytkowników, role i ich hasła z pliku _globals.sql[.gz] (jeśli istnieje). WYMAGANE do pełnego disaster recovery. Kolejność przywracania: 1. _globals.sql[.gz] – użytkownicy i role (tylko z --restore-users) 2. *.sql[.gz] – bazy danych (alfabetycznie, z pominięciem _globals) Przykłady: $(basename "$0") /home/admin/postgres_backup/19-02-2026 $(basename "$0") /home/admin/postgres_backup/19-02-2026 --restore-users Uwaga: Każda przywracana baza zostanie usunięta i odtworzona od nowa. Plik poświadczeń: ${CREDENTIALS_FILE} EOF } # --------------------------------------------------------------------------- # Parsowanie argumentów # --------------------------------------------------------------------------- BACKUP_DIR="" RESTORE_USERS=false for ARG in "$@"; do case "$ARG" in --restore-users) RESTORE_USERS=true ;; --help|-h) usage; exit 0 ;; -*) die "Nieznana flaga: ${ARG}. Użyj --help aby zobaczyć pomoc." ;; *) [[ -z "$BACKUP_DIR" ]] || die "Podano więcej niż jeden katalog. Użyj --help aby zobaczyć pomoc." BACKUP_DIR="$ARG" ;; esac done if [[ -z "$BACKUP_DIR" ]]; then usage exit 0 fi [[ -d "$BACKUP_DIR" ]] || die "Katalog nie istnieje: ${BACKUP_DIR}" # --------------------------------------------------------------------------- # Poświadczenia # --------------------------------------------------------------------------- [[ -f "$CREDENTIALS_FILE" ]] \ || die "Brak pliku poświadczeń: ${CREDENTIALS_FILE}" _perms=$(stat -c '%a' "$CREDENTIALS_FILE") [[ "$_perms" == "600" || "$_perms" == "400" ]] \ || die "Zbyt otwarte uprawnienia na ${CREDENTIALS_FILE} (${_perms}). Wymagane: 600 lub 400." _line=$(head -1 "$CREDENTIALS_FILE") PGHOST=$(echo "$_line" | cut -d: -f1) PGPORT=$(echo "$_line" | cut -d: -f2) PGUSER=$(echo "$_line" | cut -d: -f4) [[ -n "$PGHOST" && -n "$PGPORT" && -n "$PGUSER" ]] \ || die "Nieprawidłowy format pliku poświadczeń. Oczekiwany: host:port:database:user:password" export PGPASSFILE="$CREDENTIALS_FILE" # --------------------------------------------------------------------------- # Funkcja przywracająca jeden plik # --------------------------------------------------------------------------- restore_file() { local file="$1" local init_db="$2" case "$file" in *.sql.gz) gunzip -c "$file" \ | psql -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" \ --no-password -d "$init_db" return ${PIPESTATUS[1]} ;; *.sql) psql -h "$PGHOST" -p "$PGPORT" -U "$PGUSER" \ --no-password -d "$init_db" -f "$file" return $? ;; esac } # --------------------------------------------------------------------------- # Start # --------------------------------------------------------------------------- echo "" info "Katalog: ${BACKUP_DIR}" info "Serwer: ${PGHOST}:${PGPORT} Użytkownik: ${PGUSER}" info "Restore users: ${RESTORE_USERS}" echo "" ERRORS=0 RESTORED=0 # --------------------------------------------------------------------------- # 1. Globals (użytkownicy, role) – tylko z flagą --restore-users # --------------------------------------------------------------------------- if [[ "$RESTORE_USERS" == "true" ]]; then sekcja "Przywracanie użytkowników i ról (_globals)" GLOBALS_FILE="" for _f in "${BACKUP_DIR}/_globals.sql.gz" "${BACKUP_DIR}/_globals.sql"; do [[ -f "$_f" ]] && GLOBALS_FILE="$_f" && break done if [[ -z "$GLOBALS_FILE" ]]; then warn "Nie znaleziono pliku _globals.sql[.gz] w ${BACKUP_DIR} – pomijam użytkowników." else info "Plik: ${GLOBALS_FILE##*/}" # Globals przywracamy do postgres; DROP/CREATE ROLE może generować ostrzeżenia # jeśli role już istnieją – to normalne, kontynuujemy if restore_file "$GLOBALS_FILE" "postgres"; then ok "Użytkownicy i role przywrócone." RESTORED=$((RESTORED + 1)) else warn "Przywracanie globals zakończone z ostrzeżeniami – sprawdź output powyżej." ERRORS=$((ERRORS + 1)) fi fi fi # --------------------------------------------------------------------------- # 2. Bazy danych (pliki *.sql i *.sql.gz z pominięciem _globals.*) # --------------------------------------------------------------------------- sekcja "Przywracanie baz danych" # Zbierz pliki, posortuj alfabetycznie mapfile -t DB_FILES < <( find "$BACKUP_DIR" -maxdepth 1 -type f \( -name '*.sql' -o -name '*.sql.gz' \) \ ! -name '_globals.*' \ | sort ) if [[ ${#DB_FILES[@]} -eq 0 ]]; then warn "Nie znaleziono plików .sql ani .sql.gz w katalogu ${BACKUP_DIR} (poza _globals)." exit 0 fi for FILE in "${DB_FILES[@]}"; do DB_NAME=$(basename "$FILE" | sed 's/\.sql\.gz$//; s/\.sql$//') # Baza 'postgres' nie może być przywracana przez siebie (DROP DATABASE blokuje aktywne połączenie) if [[ "$DB_NAME" == "postgres" ]]; then INIT_DB="template1" else INIT_DB="postgres" fi info "→ ${DB_NAME} (${FILE##*/})" if restore_file "$FILE" "$INIT_DB"; then ok "${DB_NAME}: przywrócona." RESTORED=$((RESTORED + 1)) else warn "${DB_NAME}: przywracanie zakończone z błędem lub ostrzeżeniami." ERRORS=$((ERRORS + 1)) fi echo "" done # --------------------------------------------------------------------------- # Podsumowanie # --------------------------------------------------------------------------- sekcja "Podsumowanie" info "Przywrócono: ${RESTORED} | Błędy: ${ERRORS}" echo "" [[ "$ERRORS" -eq 0 ]] || exit 1 exit 0