101 lines
5.4 KiB
Bash
101 lines
5.4 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# Back up the current SHZ schema and restore it into a new `shz` database on
|
||
|
|
# the destination HighGo instance. Run this manually from the repository root.
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
SOURCE_SSH_HOST="${SOURCE_SSH_HOST:-root@124.243.245.42}"
|
||
|
|
SOURCE_DB_HOST="${SOURCE_DB_HOST:-39.98.44.136}"
|
||
|
|
SOURCE_DB_PORT="${SOURCE_DB_PORT:-6023}"
|
||
|
|
SOURCE_DB_NAME="${SOURCE_DB_NAME:-highgo}"
|
||
|
|
SOURCE_DB_USER="${SOURCE_DB_USER:-sysdba}"
|
||
|
|
SOURCE_SCHEMA="${SOURCE_SCHEMA:-shz}"
|
||
|
|
SOURCE_PASSWORD_FILE="${SOURCE_PASSWORD_FILE:-.codex/skills/query-shz-highgo/.password}"
|
||
|
|
|
||
|
|
TARGET_SSH_HOST="${TARGET_SSH_HOST:-root@124.243.245.42}"
|
||
|
|
TARGET_DB_HOST="${TARGET_DB_HOST:-127.0.0.1}"
|
||
|
|
TARGET_DB_PORT="${TARGET_DB_PORT:-5866}"
|
||
|
|
TARGET_DB_NAME="${TARGET_DB_NAME:-shz}"
|
||
|
|
TARGET_DB_USER="${TARGET_DB_USER:-sysdba}"
|
||
|
|
HIGHGO_BIN="${HIGHGO_BIN:-/opt/HighGo4.5.7-see/bin}"
|
||
|
|
BACKUP_DIR="${BACKUP_DIR:-backups/highgo}"
|
||
|
|
|
||
|
|
for command in ssh shasum; do
|
||
|
|
command -v "$command" >/dev/null || { echo "Missing required command: $command" >&2; exit 2; }
|
||
|
|
done
|
||
|
|
|
||
|
|
[[ -r "$SOURCE_PASSWORD_FILE" ]] || {
|
||
|
|
echo "Source password file is missing or unreadable: $SOURCE_PASSWORD_FILE" >&2
|
||
|
|
exit 2
|
||
|
|
}
|
||
|
|
|
||
|
|
read -r -s -p "Target HighGo password for ${TARGET_DB_USER}: " TARGET_PASSWORD
|
||
|
|
printf '\n'
|
||
|
|
[[ -n "$TARGET_PASSWORD" ]] || { echo "Target password cannot be empty." >&2; exit 2; }
|
||
|
|
|
||
|
|
timestamp="$(date +%Y%m%d-%H%M%S)"
|
||
|
|
mkdir -p "$BACKUP_DIR"
|
||
|
|
backup_file="$BACKUP_DIR/${SOURCE_SCHEMA}-${timestamp}.dump"
|
||
|
|
checksum_file="${backup_file}.sha256"
|
||
|
|
sequence_backup_file="$BACKUP_DIR/public-sequences-${timestamp}.dump"
|
||
|
|
sequence_checksum_file="${sequence_backup_file}.sha256"
|
||
|
|
|
||
|
|
remote_psql() {
|
||
|
|
local database="$1"
|
||
|
|
local sql="$2"
|
||
|
|
printf '%s\n' "$TARGET_PASSWORD" | ssh -o BatchMode=yes -o ConnectTimeout=10 "$TARGET_SSH_HOST" \
|
||
|
|
"IFS= read -r PGPASSWORD; export PGPASSWORD; exec '$HIGHGO_BIN/psql' -X --no-psqlrc -h '$TARGET_DB_HOST' -p '$TARGET_DB_PORT' -U '$TARGET_DB_USER' -d '$database' -v ON_ERROR_STOP=1 -Atc \"$sql\""
|
||
|
|
}
|
||
|
|
|
||
|
|
echo "Checking target instance and database name..."
|
||
|
|
remote_psql highgo 'SELECT 1' >/dev/null
|
||
|
|
if [[ "$(remote_psql highgo "SELECT 1 FROM pg_database WHERE datname = '$TARGET_DB_NAME'")" == "1" ]]; then
|
||
|
|
echo "Refusing to continue: target database '$TARGET_DB_NAME' already exists." >&2
|
||
|
|
echo "No backup or restore was performed." >&2
|
||
|
|
exit 3
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "Creating source backup: $backup_file"
|
||
|
|
source_password="$(<"$SOURCE_PASSWORD_FILE")"
|
||
|
|
printf '%s\n' "$source_password" | ssh -o BatchMode=yes -o ConnectTimeout=10 "$SOURCE_SSH_HOST" \
|
||
|
|
"IFS= read -r PGPASSWORD; export PGPASSWORD; exec '$HIGHGO_BIN/pg_dump' -Fc --no-owner --no-privileges -h '$SOURCE_DB_HOST' -p '$SOURCE_DB_PORT' -U '$SOURCE_DB_USER' -d '$SOURCE_DB_NAME' -n '$SOURCE_SCHEMA'" \
|
||
|
|
>"$backup_file"
|
||
|
|
|
||
|
|
[[ -s "$backup_file" ]] || { echo "Backup is empty; refusing to create target database." >&2; rm -f "$backup_file"; exit 4; }
|
||
|
|
shasum -a 256 "$backup_file" >"$checksum_file"
|
||
|
|
|
||
|
|
echo "Creating public-sequence dependency backup: $sequence_backup_file"
|
||
|
|
printf '%s\n' "$source_password" | ssh -o BatchMode=yes -o ConnectTimeout=10 "$SOURCE_SSH_HOST" \
|
||
|
|
"IFS= read -r PGPASSWORD; export PGPASSWORD; exec '$HIGHGO_BIN/pg_dump' -Fc --no-owner --no-privileges -h '$SOURCE_DB_HOST' -p '$SOURCE_DB_PORT' -U '$SOURCE_DB_USER' -d '$SOURCE_DB_NAME' -t 'public.*_seq'" \
|
||
|
|
>"$sequence_backup_file"
|
||
|
|
|
||
|
|
[[ -s "$sequence_backup_file" ]] || { echo "Sequence backup is empty; refusing to create target database." >&2; rm -f "$backup_file" "$sequence_backup_file"; exit 4; }
|
||
|
|
shasum -a 256 "$sequence_backup_file" >"$sequence_checksum_file"
|
||
|
|
|
||
|
|
echo "Creating target database '$TARGET_DB_NAME'..."
|
||
|
|
remote_psql highgo "CREATE DATABASE \"$TARGET_DB_NAME\"" >/dev/null
|
||
|
|
|
||
|
|
echo "Restoring schema '$SOURCE_SCHEMA' into '$TARGET_DB_NAME'..."
|
||
|
|
{ printf '%s\n' "$TARGET_PASSWORD"; cat "$sequence_backup_file"; } | ssh -o BatchMode=yes -o ConnectTimeout=10 "$TARGET_SSH_HOST" \
|
||
|
|
"IFS= read -r PGPASSWORD; export PGPASSWORD; exec '$HIGHGO_BIN/pg_restore' --single-transaction --exit-on-error --no-owner --no-privileges -h '$TARGET_DB_HOST' -p '$TARGET_DB_PORT' -U '$TARGET_DB_USER' -d '$TARGET_DB_NAME'" \
|
||
|
|
>/dev/null
|
||
|
|
{ printf '%s\n' "$TARGET_PASSWORD"; cat "$backup_file"; } | ssh -o BatchMode=yes -o ConnectTimeout=10 "$TARGET_SSH_HOST" \
|
||
|
|
"IFS= read -r PGPASSWORD; export PGPASSWORD; exec '$HIGHGO_BIN/pg_restore' --single-transaction --exit-on-error --no-owner --no-privileges -h '$TARGET_DB_HOST' -p '$TARGET_DB_PORT' -U '$TARGET_DB_USER' -d '$TARGET_DB_NAME'" \
|
||
|
|
>/dev/null
|
||
|
|
|
||
|
|
echo "Verifying restored schema..."
|
||
|
|
source_count="$(printf '%s\n' "$source_password" | ssh -o BatchMode=yes -o ConnectTimeout=10 "$SOURCE_SSH_HOST" \
|
||
|
|
"IFS= read -r PGPASSWORD; export PGPASSWORD; exec '$HIGHGO_BIN/psql' -X --no-psqlrc -h '$SOURCE_DB_HOST' -p '$SOURCE_DB_PORT' -U '$SOURCE_DB_USER' -d '$SOURCE_DB_NAME' -Atc \"SELECT count(*) FROM information_schema.tables WHERE table_schema = '$SOURCE_SCHEMA' AND table_type = 'BASE TABLE'\"")"
|
||
|
|
target_count="$(remote_psql "$TARGET_DB_NAME" "SELECT count(*) FROM information_schema.tables WHERE table_schema = '$SOURCE_SCHEMA' AND table_type = 'BASE TABLE'")"
|
||
|
|
|
||
|
|
if [[ "$source_count" != "$target_count" ]]; then
|
||
|
|
echo "Verification failed: source has $source_count tables, target has $target_count." >&2
|
||
|
|
exit 5
|
||
|
|
fi
|
||
|
|
|
||
|
|
unset TARGET_PASSWORD source_password
|
||
|
|
echo "Migration complete. Backup: $backup_file"
|
||
|
|
echo "Checksum: $checksum_file"
|
||
|
|
echo "Sequence backup: $sequence_backup_file"
|
||
|
|
echo "Sequence checksum: $sequence_checksum_file"
|
||
|
|
echo "Verified base tables in schema '$SOURCE_SCHEMA': $target_count"
|