#!/bin/bash # ============================================================================== # PostgreSQL Verify Backup Integrity — ověření konzistence po restore # ============================================================================== # # CO DĚLÁ: # Připojí se k PostgreSQL 18 a pro každou databázi zkontroluje: # 1. Konektivitu k serveru # 2. Seznam všech databází # 3. Pro každou DB: počet tabulek, počty řádků, velikosti, počet indexů # 4. PostgreSQL role a uživatele # # KDY POUŽÍT: # Po provedení postgresqlrestore_from_backup.sh — ověří, že data jsou v pořádku. # Spouštět ručně, není součástí automatizovaného schedule. # # VÝSTUP: # OK / ERROR indikátory, tabulky se statistikami. # Skript vrátí exit code 1 pokud cokoliv selže. # ============================================================================== set -x # ============================================================================== # KONFIGURACE # ============================================================================== CONTAINER_NAME="postgresql18" PG_HOST="localhost" PG_PORT="5432" PG_USER="vladimir.buzalka" export PGPASSWORD="Vlado7309208104++" echo "Starting PostgreSQL backup integrity verification..." echo "==========================================" ALL_OK=true # ============================================================================== # 1. KONEKTIVITA # Jednoduchý SELECT 'connected' — pokud selže, PostgreSQL není dostupný # a nemá smysl pokračovat. # ============================================================================== echo "" echo "Checking PostgreSQL connectivity..." docker exec \ -e PGPASSWORD="$PGPASSWORD" \ "$CONTAINER_NAME" \ psql \ --host="$PG_HOST" \ --port="$PG_PORT" \ --username="$PG_USER" \ --dbname="postgres" \ --tuples-only \ --command="SELECT 'connected';" > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "ERROR: Cannot connect to PostgreSQL!" exit 1 fi echo "OK: Connected to PostgreSQL" # ============================================================================== # 2. SEZNAM DATABÁZÍ # pg_database: systémová tabulka s metadaty databází. # datistemplate=false: vynechá šablonové DB (template0, template1). # Výsledek jde nejdřív na stdout (pro přehled), pak do proměnné pro iteraci. # ============================================================================== echo "" echo "Databases present:" docker exec \ -e PGPASSWORD="$PGPASSWORD" \ "$CONTAINER_NAME" \ psql \ --host="$PG_HOST" \ --port="$PG_PORT" \ --username="$PG_USER" \ --dbname="postgres" \ --tuples-only \ --command="SELECT datname FROM pg_database WHERE datistemplate = false ORDER BY datname;" # Znovu spustíme dotaz pro iteraci — ukládáme do proměnné. # tr -d ' ': odstraní bílé znaky z výstupu psql (odsazení sloupce). DATABASES=$(docker exec \ -e PGPASSWORD="$PGPASSWORD" \ "$CONTAINER_NAME" \ psql \ --host="$PG_HOST" \ --port="$PG_PORT" \ --username="$PG_USER" \ --dbname="postgres" \ --tuples-only \ --command="SELECT datname FROM pg_database WHERE datistemplate = false ORDER BY datname;" \ | tr -d ' ') # ============================================================================== # 3. KONTROLA KAŽDÉ DATABÁZE # ============================================================================== for DB_NAME in $DATABASES; do [ -z "$DB_NAME" ] && continue # přeskoč prázdné řádky z výstupu psql echo "" echo "Verifying database: $DB_NAME" echo "------------------------------------------" # -------------------------------------------------------------------------- # Počet tabulek v public schema # information_schema.tables: standardní SQL pohled, table_schema='public' # filtruje jen uživatelské tabulky (ne systémové views). # -------------------------------------------------------------------------- TABLE_COUNT=$(docker exec \ -e PGPASSWORD="$PGPASSWORD" \ "$CONTAINER_NAME" \ psql \ --host="$PG_HOST" \ --port="$PG_PORT" \ --username="$PG_USER" \ --dbname="$DB_NAME" \ --tuples-only \ --command="SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';" \ | tr -d ' ') echo "OK: Tables in public schema: $TABLE_COUNT" # -------------------------------------------------------------------------- # Tabulky s počtem řádků a velikostí # pg_stat_user_tables: statistiky o uživatelských tabulkách (live tuples, dead tuples). # n_live_tup: odhadovaný počet živých řádků (ANALYZE musí být aktuální). # pg_total_relation_size: celková velikost incl. indexy a TOAST. # -------------------------------------------------------------------------- echo " Table row counts:" docker exec \ -e PGPASSWORD="$PGPASSWORD" \ "$CONTAINER_NAME" \ psql \ --host="$PG_HOST" \ --port="$PG_PORT" \ --username="$PG_USER" \ --dbname="$DB_NAME" \ --tuples-only \ --command=" SELECT schemaname || '.' || relname AS table_name, n_live_tup AS estimated_rows, pg_size_pretty(pg_total_relation_size(relid)) AS total_size FROM pg_stat_user_tables ORDER BY relname;" # -------------------------------------------------------------------------- # Počet indexů v public schema # pg_indexes: systémový katalog indexů. Slouží jako ověření, že # pg_dumpall správně obnovil i CREATE INDEX příkazy (ne jen data). # -------------------------------------------------------------------------- INDEX_COUNT=$(docker exec \ -e PGPASSWORD="$PGPASSWORD" \ "$CONTAINER_NAME" \ psql \ --host="$PG_HOST" \ --port="$PG_PORT" \ --username="$PG_USER" \ --dbname="$DB_NAME" \ --tuples-only \ --command="SELECT COUNT(*) FROM pg_indexes WHERE schemaname = 'public';" \ | tr -d ' ') echo "OK: Indexes in public schema: $INDEX_COUNT" # -------------------------------------------------------------------------- # Celková velikost databáze # pg_database_size: vrátí velikost v bytech, pg_size_pretty ji naformátuje. # -------------------------------------------------------------------------- DB_SIZE=$(docker exec \ -e PGPASSWORD="$PGPASSWORD" \ "$CONTAINER_NAME" \ psql \ --host="$PG_HOST" \ --port="$PG_PORT" \ --username="$PG_USER" \ --dbname="$DB_NAME" \ --tuples-only \ --command="SELECT pg_size_pretty(pg_database_size('$DB_NAME'));" \ | tr -d ' ') echo "OK: Database size: $DB_SIZE" done # ============================================================================== # 4. ROLE A UŽIVATELÉ # pg_roles: systémový katalog všech rolí. # Filtrujeme pryč built-in pg_* role (pg_monitor, pg_read_all_settings, atd.) # aby výstup byl přehledný — zajímají nás jen uživatelské role. # ============================================================================== echo "" echo "PostgreSQL roles:" docker exec \ -e PGPASSWORD="$PGPASSWORD" \ "$CONTAINER_NAME" \ psql \ --host="$PG_HOST" \ --port="$PG_PORT" \ --username="$PG_USER" \ --dbname="postgres" \ --command="SELECT rolname, rolsuper, rolcreatedb, rolcanlogin FROM pg_roles WHERE rolname NOT LIKE 'pg_%' ORDER BY rolname;" echo "" echo "==========================================" if [ "$ALL_OK" = true ]; then echo "OK: All verifications passed!" else echo "ERROR: Some verifications failed!" exit 1 fi set +x