Skip to content

Instantly share code, notes, and snippets.

@lbrito1
Created June 5, 2025 23:14
Show Gist options
  • Select an option

  • Save lbrito1/3718265ec27ae5e90af76e660b8afebc to your computer and use it in GitHub Desktop.

Select an option

Save lbrito1/3718265ec27ae5e90af76e660b8afebc to your computer and use it in GitHub Desktop.
full_db_restore.sh
#!/bin/bash
# Combined DB Download and Restore Script
# Usage: ./combined_restore.sh <S3_URL> <DB_URL> [DB_NAME] [DUMP_PATH]
# Example: nohup ./combined_restore.sh "https://s3-url..." "postgres://user:pass@host:port" "frdm" "/data/db_dump" > restore_full.log 2>&1 &
set -e # Exit on any error
# Check arguments
if [ $# -lt 2 ]; then
echo "Usage: $0 <S3_URL> <DB_URL> [DB_NAME] [DUMP_PATH]"
echo " S3_URL - S3 presigned URL for the database dump"
echo " DB_URL - PostgreSQL connection URL"
echo " DB_NAME - Database name (default: frdm)"
echo " DUMP_PATH - Local path for dump file (default: /data/db_dump)"
echo ""
echo "Example:"
echo " $0 \"https://bucket.s3.amazonaws.com/backup.sql\" \"postgres://user:pass@host:5432\" \"mydb\" \"/tmp/dump\""
exit 1
fi
S3_URL="$1"
DB_URL="$2"
DB_NAME="${3:-frdm}"
DB_DUMP_PATH="${4:-/data/db_dump}"
echo "$(date): Starting combined DB restore process..."
echo "$(date): S3 URL: $S3_URL"
echo "$(date): DB URL: $DB_URL"
echo "$(date): DB Name: $DB_NAME"
echo "$(date): Dump Path: $DB_DUMP_PATH"
# Step 1: Download the database dump
echo "$(date): Starting database dump download..."
curl "$S3_URL" -o "$DB_DUMP_PATH"
if [ $? -eq 0 ]; then
echo "$(date): Database dump downloaded successfully to $DB_DUMP_PATH"
# Check if file exists and has content
if [ -s "$DB_DUMP_PATH" ]; then
echo "$(date): File size: $(du -h $DB_DUMP_PATH | cut -f1)"
else
echo "$(date): Error: Downloaded file is empty!"
exit 1
fi
else
echo "$(date): Error: Failed to download database dump"
exit 1
fi
# Step 2: Execute database restore function
echo "$(date): Starting database restore..."
# Embedded database restore function
restore_database() {
local CONNECTION_STRING="$1"
local DB_NAME="$2"
local IMPORT_FILE="$3"
# --- Parse the Connection String to set environment variables ---
# This ensures psql and createdb can connect using these details.
# Extract everything after the protocol (e.g., 'user:pass@host:port/optional_db')
HOST_PART=$(echo "$CONNECTION_STRING" | sed -E 's/^[a-z]+:\/\///')
# Extract user:password part (if present)
if [[ "$HOST_PART" =~ ^([^:]+)(:([^@]+))?@ ]]; then
export PGUSER="${BASH_REMATCH[1]}"
export PGPASSWORD="${BASH_REMATCH[3]}" # Will be empty if no password
HOST_PART="${HOST_PART#*@}" # Remove user:pass@
fi
# Extract host:port (and optional database name from URI, though we'll use the DB_NAME argument)
if [[ "$HOST_PART" =~ ^([^:]+)(:([0-9]+))?(\/(.*))?$ ]]; then
export PGHOST="${BASH_REMATCH[1]}"
export PGPORT="${BASH_REMATCH[3]}" # Will be empty if no port
# The database name from the URI path is in ${BASH_REMATCH[5]}, but we're ignoring it for operations.
fi
# --- End Connection String Parsing ---
# ANSI color codes
GREEN='\033[0;32m' # Green color
NC='\033[0m' # No color
echo "$(date): Step 0: Drop old database '$DB_NAME'..."
# Connect to the default 'postgres' database to drop the target database
# psql will use PGUSER, PGPASSWORD, PGHOST, PGPORT from environment variables
psql -d postgres -c "DROP DATABASE IF EXISTS \"$DB_NAME\";"
echo "$(date): Step 1: Creating the new database '$DB_NAME'..."
# createdb will use PGUSER, PGPASSWORD, PGHOST, PGPORT from environment variables
createdb "$DB_NAME"
# Check if database creation was successful
if [ $? -ne 0 ]; then
echo "$(date): Error: Failed to create database $DB_NAME."
return 1
fi
echo "$(date): Step 2: Creating the 'blazer' role and granting privileges..."
# Connect to the newly created database to set up roles and privileges
psql -d "$DB_NAME" -c "DO \$\$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'blazer') THEN CREATE ROLE blazer LOGIN PASSWORD 'change-me-later'; END IF; END \$\$;"
psql -d "$DB_NAME" -c "GRANT CONNECT ON DATABASE \"$DB_NAME\" TO blazer;"
psql -d "$DB_NAME" -c "GRANT USAGE ON SCHEMA public TO blazer;"
psql -d "$DB_NAME" -c "GRANT SELECT ON ALL TABLES IN SCHEMA public TO blazer;"
psql -d "$DB_NAME" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO blazer;"
echo "$(date): Step 3: Importing data from $IMPORT_FILE with FK constraints temporarily disabled..."
# Connect to the target database for the import
psql -d "$DB_NAME" -c "SET session_replication_role = replica;" -f "$IMPORT_FILE"
# Check if the import command failed
if [ $? -ne 0 ]; then
echo "$(date): Error: psql command failed during import."
return 1
fi
echo -e "$(date): ${GREEN}Import and role creation completed successfully.${NC}"
return 0
}
# Call the restore function
restore_database "$DB_URL" "$DB_NAME" "$DB_DUMP_PATH"
if [ $? -eq 0 ]; then
echo "$(date): Database restore completed successfully!"
else
echo "$(date): Error: Database restore failed"
exit 1
fi
echo "$(date): Combined DB restore process completed successfully!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment