erp-core/docs/07-devops/scripts/restore-postgres.sh

141 lines
4.2 KiB
Bash
Executable File

#!/bin/bash
# =====================================================
# ERP GENERIC - PostgreSQL Restore Script
# Restores database from backup file
# =====================================================
set -euo pipefail
# Usage
if [ $# -lt 1 ]; then
echo "Usage: $0 <backup_file> [--target=<database>] [--no-prompt]"
echo ""
echo "Examples:"
echo " $0 /backups/postgres/full_20251124_020000.dump"
echo " $0 /backups/postgres/full_20251124_020000.dump --target=erp_generic_staging"
echo " $0 /backups/postgres/full_20251124_020000.dump --no-prompt"
echo ""
exit 1
fi
BACKUP_FILE="$1"
TARGET_DB="${2:-erp_generic}"
NO_PROMPT=false
# Parse arguments
for arg in "$@"; do
case $arg in
--target=*)
TARGET_DB="${arg#*=}"
shift
;;
--no-prompt)
NO_PROMPT=true
shift
;;
esac
done
DB_HOST="${POSTGRES_HOST:-postgres}"
DB_USER="${POSTGRES_USER:-erp_user}"
PGPASSWORD="${POSTGRES_PASSWORD}"
export PGPASSWORD
# Logging
LOG_FILE="/var/log/erp-generic/restore.log"
exec > >(tee -a "$LOG_FILE")
exec 2>&1
echo "===== PostgreSQL Restore Started at $(date) ====="
echo "Backup file: $BACKUP_FILE"
echo "Target database: $TARGET_DB"
# Verify backup file exists
if [ ! -f "$BACKUP_FILE" ]; then
echo "✗ Backup file not found: $BACKUP_FILE"
exit 1
fi
# Verify checksum if exists
if [ -f "${BACKUP_FILE}.md5" ]; then
echo "Verifying backup integrity..."
md5sum -c "${BACKUP_FILE}.md5"
if [ $? -ne 0 ]; then
echo "✗ Backup integrity check failed!"
exit 1
fi
echo "✓ Backup integrity verified"
fi
# Safety prompt (unless --no-prompt)
if [ "$NO_PROMPT" = false ]; then
echo ""
echo "⚠️ WARNING: This will OVERWRITE all data in database '$TARGET_DB'"
echo "⚠️ Make sure you have a recent backup before proceeding!"
echo ""
read -p "Are you sure you want to continue? (yes/no): " -r
if [[ ! $REPLY =~ ^[Yy][Ee][Ss]$ ]]; then
echo "Restore cancelled by user."
exit 0
fi
fi
# Create safety backup of target database (if not staging/dev)
if [[ ! "$TARGET_DB" =~ (staging|dev|test) ]]; then
echo "Creating safety backup of $TARGET_DB before restore..."
SAFETY_BACKUP="/backups/postgres/safety_${TARGET_DB}_$(date +%Y%m%d_%H%M%S).dump"
pg_dump -h "$DB_HOST" -U "$DB_USER" -Fc -d "$TARGET_DB" -f "$SAFETY_BACKUP"
echo "✓ Safety backup created: $SAFETY_BACKUP"
fi
# Terminate active connections to target database
echo "Terminating active connections to $TARGET_DB..."
psql -h "$DB_HOST" -U "$DB_USER" -d postgres <<SQL
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = '$TARGET_DB' AND pid <> pg_backend_pid();
SQL
# Restore database
echo "Restoring database from $BACKUP_FILE..."
pg_restore -h "$DB_HOST" -U "$DB_USER" -d "$TARGET_DB" --clean --if-exists --verbose "$BACKUP_FILE"
if [ $? -eq 0 ]; then
echo "✓ Database restored successfully"
else
echo "✗ Restore failed!"
exit 1
fi
# Verify restore
echo "Verifying restore..."
TABLE_COUNT=$(psql -h "$DB_HOST" -U "$DB_USER" -d "$TARGET_DB" -tAc "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema NOT IN ('pg_catalog', 'information_schema');")
USER_COUNT=$(psql -h "$DB_HOST" -U "$DB_USER" -d "$TARGET_DB" -tAc "SELECT COUNT(*) FROM auth.users;" 2>/dev/null || echo "N/A")
echo "Tables restored: $TABLE_COUNT"
echo "Users in auth.users: $USER_COUNT"
# Rebuild statistics
echo "Rebuilding database statistics..."
psql -h "$DB_HOST" -U "$DB_USER" -d "$TARGET_DB" -c "ANALYZE;"
echo "✓ Statistics rebuilt"
# Send notification (optional)
if [ -n "${SLACK_WEBHOOK_URL:-}" ]; then
curl -X POST "$SLACK_WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-d "{\"text\": \"✅ PostgreSQL restore completed\n• Database: $TARGET_DB\n• From backup: $(basename $BACKUP_FILE)\n• Tables restored: $TABLE_COUNT\n• Restored by: $USER\"}"
fi
echo "===== PostgreSQL Restore Completed at $(date) ====="
echo ""
echo "Next steps:"
echo "1. Verify application functionality"
echo "2. Run smoke tests: npm run test:smoke"
echo "3. Check logs for errors: docker-compose logs -f backend"
echo "4. Notify team that restore is complete"
echo ""
# Exit successfully
exit 0