Files
da-postgresql/scripts/setup/restore_all.sh
T
2026-07-04 16:00:04 +02:00

212 lines
7.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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 <<EOF
Użycie:
$(basename "$0") <katalog_backupu> [--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