spb/datacenterindex
Public
HTML 53.9%
TypeScript 44.5%
JavaScript 0.6%
SQL 0.5%
1#!/usr/bin/env bash2# restore.sh <dump> [--db dci_restore] [--swap]3# <dump> local path (copied to the data node) or a remote path under /srv/dci/backups/pg/ (or `latest`)4# Restores into a SEPARATE database (default dci_restore) so production is never touched by accident.5# --swap after a successful restore, stop api/scheduler, rename dci → dci_old_<stamp> and dci_restore → dci,6# restart. (Reversible: rename back.)7source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"8dump="${1:-}"; [[ -n $dump ]] || die "usage: restore.sh <dump.dump|latest> [--db name] [--swap]"9shift10db="dci_restore"; swap=011while [[ $# -gt 0 ]]; do12 case "$1" in --db) db="$2"; shift ;; --swap) swap=1 ;; *) die "unknown flag $1" ;; esac; shift13done14[[ $db =~ ^[a-z_][a-z0-9_]*$ ]] || die "bad db name"15[[ $db != dci ]] || die "refusing to restore directly into 'dci' — restore into dci_restore and use --swap"1617if [[ $dump == latest ]]; then18 remote_dump="$(remote data "ls -1t $BACKUP_DIR/pg/*.dump | head -1")"19elif [[ -f $dump ]]; then20 log "copy $dump → $(host_for data):$BACKUP_DIR/pg/"21 rsync -az --info=progress2 -e "ssh ${SSH_OPTS[*]}" "$dump" "$(host_for data):$BACKUP_DIR/pg/"22 remote_dump="$BACKUP_DIR/pg/$(basename "$dump")"23else24 remote_dump="$dump"25 remote data "test -f '$remote_dump'" || die "no such file on data node: $remote_dump"26fi27in_container="/backups/$(basename "$remote_dump")" # /srv/dci/backups/pg is mounted at /backups in postgres28log "restore $remote_dump → database $db"2930compose data "exec -T postgres psql -U dci -d postgres -v ON_ERROR_STOP=1 -c \"DROP DATABASE IF EXISTS $db WITH (FORCE)\" -c \"CREATE DATABASE $db OWNER dci TEMPLATE template0 ENCODING 'UTF8' LOCALE 'C.UTF-8'\""31compose data "exec -T postgres psql -U dci -d $db -v ON_ERROR_STOP=1 -c 'CREATE EXTENSION IF NOT EXISTS pg_trgm' -c 'CREATE EXTENSION IF NOT EXISTS unaccent'"32compose data "exec -T postgres pg_restore -U dci -d $db --no-owner --role=dci --jobs=4 --exit-on-error $in_container"33compose data "exec -T postgres psql -U dci -d $db -Atc \"select 'tables: '||count(*) from information_schema.tables where table_schema='public'\" -Atc \"select 'facilities: '||count(*) from facilities\" -Atc \"select 'migrations: '||count(*) from _dci_migrations\"" || true34ok "restored into $db"3536if [[ $swap == 1 ]]; then37 stamp="$(date +%Y%m%d%H%M)"38 warn "swapping $db → dci (old data kept as dci_old_$stamp)"39 compose data "stop api scheduler worker-maint" || true40 compose crawl "stop worker worker-b" || warn "crawl workers not stopped (unreachable?) — stop them manually"41 compose data "exec -T postgres psql -U dci -d postgres -v ON_ERROR_STOP=1 \42 -c \"SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname IN ('dci','$db') AND pid <> pg_backend_pid()\" \43 -c \"ALTER DATABASE dci RENAME TO dci_old_$stamp\" -c \"ALTER DATABASE $db RENAME TO dci\""44 compose data "up -d api scheduler"45 compose crawl "up -d" || true46 ok "swapped; previous database is dci_old_$stamp (drop it when satisfied: psql.sh -c 'DROP DATABASE dci_old_$stamp')"47fi48