chore(db): rename dev database to prop_dev, add prod restore script
Rename the local dev database from microwaveprop_dev to prop_dev so the name matches the production database. Add scripts/restore_prod_to_local.sh, which pulls the latest pg_dump off the backup server, drops the local prop_dev, recreates it, and pg_restores into it.
This commit is contained in:
parent
b675a4badc
commit
fa0f2828a6
3 changed files with 92 additions and 2 deletions
|
|
@ -8,7 +8,7 @@ config :microwaveprop, Microwaveprop.Repo,
|
|||
username: "postgres",
|
||||
password: "postgres",
|
||||
hostname: "localhost",
|
||||
database: "microwaveprop_dev",
|
||||
database: "prop_dev",
|
||||
stacktrace: true,
|
||||
show_sensitive_data_on_connection_error: true,
|
||||
pool_size: 30
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ Copy shape from `lib/microwaveprop/weather/hrrr_profile.ex`, strip anything RDPS
|
|||
|
||||
```bash
|
||||
mix ecto.migrate
|
||||
psql -h localhost -d microwaveprop_dev -c "\d rdps_profiles"
|
||||
psql -h localhost -d prop_dev -c "\d rdps_profiles"
|
||||
```
|
||||
|
||||
**Step 2.5: Run schema test, verify PASS**
|
||||
|
|
|
|||
90
scripts/restore_prod_to_local.sh
Executable file
90
scripts/restore_prod_to_local.sh
Executable file
|
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Pull the latest production Postgres dump off the DB server and restore
|
||||
# it into the local `prop_dev` database, replacing whatever is there.
|
||||
#
|
||||
# The production server runs scripts/backup_prop_db.sh on a daily cron,
|
||||
# which writes pg_dump custom-format dumps to /backups/prop/ as
|
||||
# `prop_YYYYMMDD_HHMMSS.dump`. We SSH in, pick the newest one, scp it
|
||||
# locally, then drop/recreate prop_dev and restore into it.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# scripts/restore_prod_to_local.sh
|
||||
# REMOTE_HOST=my-db-host REMOTE_USER=graham scripts/restore_prod_to_local.sh
|
||||
#
|
||||
# Before running: stop `mix phx.server` so Ecto doesn't hold connections.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
REMOTE_HOST="${REMOTE_HOST:-db-prop}"
|
||||
REMOTE_USER="${REMOTE_USER:-$USER}"
|
||||
REMOTE_BACKUP_DIR="${REMOTE_BACKUP_DIR:-/backups/prop}"
|
||||
LOCAL_DB="${LOCAL_DB:-prop_dev}"
|
||||
LOCAL_USER="${LOCAL_USER:-postgres}"
|
||||
LOCAL_HOST="${LOCAL_HOST:-localhost}"
|
||||
LOCAL_TMP="${LOCAL_TMP:-/tmp}"
|
||||
|
||||
ssh_target="${REMOTE_USER}@${REMOTE_HOST}"
|
||||
|
||||
log() {
|
||||
printf '%s restore_prod_to_local: %s\n' "$(date -u +'%Y-%m-%dT%H:%M:%SZ')" "$*"
|
||||
}
|
||||
|
||||
die() {
|
||||
log "ERROR: $*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
command -v ssh >/dev/null || die "ssh not on PATH"
|
||||
command -v scp >/dev/null || die "scp not on PATH"
|
||||
command -v pg_restore >/dev/null || die "pg_restore not on PATH (install postgresql client tools)"
|
||||
command -v psql >/dev/null || die "psql not on PATH"
|
||||
|
||||
log "looking up latest dump on ${ssh_target}:${REMOTE_BACKUP_DIR}"
|
||||
remote_file=$(ssh "$ssh_target" "ls -1t ${REMOTE_BACKUP_DIR}/prop_*.dump 2>/dev/null | head -n1")
|
||||
[[ -n "$remote_file" ]] || die "no prop_*.dump files found in ${REMOTE_BACKUP_DIR} on ${REMOTE_HOST}"
|
||||
|
||||
filename=$(basename "$remote_file")
|
||||
local_file="${LOCAL_TMP}/${filename}"
|
||||
log "latest dump: ${remote_file}"
|
||||
|
||||
# Always remove the downloaded dump, even on mid-run failure. Saves disk
|
||||
# on laptops where dumps are multi-GB.
|
||||
cleanup() {
|
||||
[[ -n "${local_file:-}" && -f "$local_file" ]] && rm -f "$local_file"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
log "downloading to ${local_file}"
|
||||
scp "${ssh_target}:${remote_file}" "$local_file"
|
||||
|
||||
# Kick any existing connections off the DB before dropping it — otherwise
|
||||
# `DROP DATABASE` fails with "is being accessed by other users". This is
|
||||
# aggressive, but it's a dev box and the user was told to stop the server.
|
||||
log "terminating existing connections to ${LOCAL_DB}"
|
||||
psql -h "$LOCAL_HOST" -U "$LOCAL_USER" -d postgres -v ON_ERROR_STOP=1 <<SQL >/dev/null
|
||||
SELECT pg_terminate_backend(pid)
|
||||
FROM pg_stat_activity
|
||||
WHERE datname = '${LOCAL_DB}' AND pid <> pg_backend_pid();
|
||||
SQL
|
||||
|
||||
log "dropping and recreating ${LOCAL_DB}"
|
||||
psql -h "$LOCAL_HOST" -U "$LOCAL_USER" -d postgres -v ON_ERROR_STOP=1 <<SQL >/dev/null
|
||||
DROP DATABASE IF EXISTS ${LOCAL_DB};
|
||||
CREATE DATABASE ${LOCAL_DB} OWNER ${LOCAL_USER};
|
||||
SQL
|
||||
|
||||
# --no-owner / --no-acl so ownership in the prod dump doesn't cause role
|
||||
# errors locally. -j 4 parallelises table data restore.
|
||||
log "restoring dump into ${LOCAL_DB}"
|
||||
pg_restore \
|
||||
-h "$LOCAL_HOST" \
|
||||
-U "$LOCAL_USER" \
|
||||
-d "$LOCAL_DB" \
|
||||
--no-owner \
|
||||
--no-acl \
|
||||
-j 4 \
|
||||
"$local_file"
|
||||
|
||||
log "done — ${LOCAL_DB} is a copy of prod as of $(basename "$filename" .dump)"
|
||||
Loading…
Add table
Reference in a new issue