chore: add 2 tools to backup and restore DB
This commit is contained in:
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
NOW="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||
|
||||
pg_dump postgres://postgres:postgres@localhost:5432/oxicloud -F c --disable-triggers > "backup.${NOW}.dump"
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
# scripts/restore.sh — restore a pg_dump custom-format snapshot into a
|
||||
# fresh oxicloud DB.
|
||||
#
|
||||
# Drops + recreates the whole DB before restoring so migrations added
|
||||
# AFTER the dump was taken don't block --clean's DROPs. Symptom of
|
||||
# that class (hit 2026-08-30):
|
||||
#
|
||||
# pg_restore: erreur : ...
|
||||
# cannot drop constraint files_pkey on table storage.files because
|
||||
# other objects depend on it
|
||||
# DÉTAIL : constraint file_attached_blobs_file_id_fkey on table
|
||||
# storage.file_attached_blobs depends on index storage.files_pkey
|
||||
#
|
||||
# The dump only knows about objects that existed at dump time;
|
||||
# `pg_restore --clean` DROPs exactly those. Anything added since
|
||||
# (`file_attached_blobs` in the example above) survives and blocks
|
||||
# DROPs of things it depends on. Drop-and-recreate the whole DB
|
||||
# sidesteps the problem entirely.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/restore.sh <dump-file>
|
||||
#
|
||||
# Companion of the pg_dump command in memory
|
||||
# bug_pg_dump_folders_circular_fk.md:
|
||||
# pg_dump postgres://... -F c --disable-triggers > backup.$NOW.dump
|
||||
#
|
||||
# NB: this restores the DB ONLY. Blob storage on disk
|
||||
# (${OXICLOUD_STORAGE_PATH}) is NOT touched — snapshot + restore that
|
||||
# separately with rsync if you need lockstep DB/disk state.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
DUMP="${1:?usage: $0 <dump-file>}"
|
||||
[[ -f "$DUMP" ]] || { echo "[restore] ERROR: dump file not found: $DUMP" >&2; exit 1; }
|
||||
|
||||
# Admin connection — connect to the `postgres` maintenance DB so we can
|
||||
# drop `oxicloud` itself (can't drop the DB you're connected to). Both
|
||||
# connection strings share credentials from the sandbox setup.
|
||||
ADMIN="postgres://postgres:postgres@localhost:5432/postgres"
|
||||
TARGET="postgres://postgres:postgres@localhost:5432/oxicloud"
|
||||
|
||||
# 1. Terminate every connection to `oxicloud` so DROP DATABASE can
|
||||
# proceed. OxiCloud running against 5432? rust-analyzer with
|
||||
# sqlx-cli open? Any lingering psql session? All of them block
|
||||
# `DROP DATABASE` with "database is being accessed by other users".
|
||||
# pg_terminate_backend kicks them cleanly (they'll reconnect if
|
||||
# they retry).
|
||||
echo "[restore] Terminating connections to oxicloud..."
|
||||
psql "$ADMIN" -c "
|
||||
SELECT pg_terminate_backend(pid)
|
||||
FROM pg_stat_activity
|
||||
WHERE datname = 'oxicloud'
|
||||
AND pid <> pg_backend_pid();
|
||||
" >/dev/null
|
||||
|
||||
# 2. Drop + recreate. IF EXISTS on DROP so a fresh workstation without
|
||||
# an existing `oxicloud` database doesn't error on the first-ever
|
||||
# invocation.
|
||||
echo "[restore] Dropping + recreating oxicloud database..."
|
||||
psql "$ADMIN" <<'SQL'
|
||||
DROP DATABASE IF EXISTS oxicloud;
|
||||
CREATE DATABASE oxicloud OWNER postgres;
|
||||
SQL
|
||||
|
||||
# 3. Restore. `--clean --if-exists` no longer needed (fresh DB from
|
||||
# step 2). The remaining flags:
|
||||
#
|
||||
# * --disable-triggers — turn triggers off during data load so the
|
||||
# `storage.folders.parent_id` self-FK doesn't reject rows whose
|
||||
# parent hasn't been inserted yet in the same COPY batch. See
|
||||
# memory bug_pg_dump_folders_circular_fk for background.
|
||||
# * --single-transaction — atomic restore (all-or-nothing) AND
|
||||
# lets --disable-triggers work without superuser (superuser is
|
||||
# required otherwise).
|
||||
# * --no-owner --no-privileges — portable, ignores ownership /
|
||||
# GRANTs from the source system so a dump taken from one machine
|
||||
# restores cleanly on another with different user names.
|
||||
echo "[restore] Restoring from $DUMP..."
|
||||
pg_restore \
|
||||
--disable-triggers \
|
||||
--single-transaction \
|
||||
--no-owner \
|
||||
--no-privileges \
|
||||
-d "$TARGET" \
|
||||
"$DUMP"
|
||||
|
||||
echo "[restore] Done. Database restored to snapshot state in $DUMP."
|
||||
Reference in New Issue
Block a user