minibikini/pgsafe

★ 0Forks 0GoGitHub ↗Compare

README

pgsafe

Safe PostgreSQL recovery tooling for humans and autonomous agents.

pgsafe brings automated, verifiable safety to PostgreSQL disaster recovery. It discovers cluster facts, evaluates health, plans and converges backup configurations, takes on-demand backups, executes non-destructive recovery drills in isolated sandboxes, and restores clusters to separate target directories—all with strict fail-closed safety semantics.


The Recovery Invariant

False negatives are acceptable. False confidence is prohibited. pgsafe never returns SAFE, SUCCESS, VERIFIED, or CONVERGED without positive semantic proof.

SAFE does not mean "disks will never fail or corruption is impossible." It proves an exact contract:

  1. PostgreSQL is up and inspectable.
  2. At least one successful WAL archive event has been observed via last_archived_at.
  3. At least one valid base backup metadata entry exists in the repository matching the target cluster identity.
  4. A non-destructive recovery drill has verified the backup within the last 30 days and matches the primary cluster's system_identifier.

Supported Scope (v0.1)

  • Operating Systems: Debian / Ubuntu (systemd-managed)
  • PostgreSQL Versions: 15, 16, 17, 18
  • Topology: Single exact cluster on host
  • Backup Engine: pgBackRest (POSIX filesystem or S3 repository)

What pgsafe Deliberately Does NOT Do in v0.1

  • No in-place live PGDATA overwrites: Restores are strictly isolated into a separate directory to prevent accidental destruction of production data.
  • No user tablespace restores: Backups containing tablespaces outside PGDATA are rejected before mutation to prevent collateral filesystem damage.
  • No multi-cluster guessing: If multiple running clusters are detected, operations refuse to guess and fail closed.
  • No remote cluster orchestration: Designed for local host agent/operator execution.

Installation & Building

Prerequisites

  • Debian 12+ or Ubuntu 22.04+ with systemd and active PostgreSQL 15–18 (installed via distro packages or the official PGDG apt repository). Note: pgbackrest does not need to be manually pre-installed; pgsafe plan detects if it is absent and includes package installation in the plan, which pgsafe apply then executes.
  • Go 1.27+ (or run mise install) to build from source
  • Privilege Requirements: The standard production workflow should be run with sudo. Local PostgreSQL connections default to peer authentication on Debian/Ubuntu, and apply requires root privileges to write configuration files under /etc, manage systemd units, and restart services. (The postgres user is sufficient for some read-only cluster inspection, but not for apply or systemd operations.)

Compiling

# Build native binary
mise run build
# Or: go build -o bin/pgsafe .

# Cross-compile for Linux servers (arm64 / amd64)
mise run build:linux-arm64
mise run build:linux

Installation

# Copy binary into system PATH for sudo access
sudo install -m 0755 bin/pgsafe /usr/local/bin/pgsafe
# Or on Linux target when cross-compiled (amd64 / arm64):
# sudo install -m 0755 bin/pgsafe-linux-amd64 /usr/local/bin/pgsafe
# sudo install -m 0755 bin/pgsafe-linux-arm64 /usr/local/bin/pgsafe

Standard Workflow

# 1. Diagnose current health and recoverability (exits 2 UNSAFE on fresh unconfigured cluster)
sudo pgsafe doctor

# 2. Preview or save configuration plan for POSIX or S3 repository
sudo pgsafe plan --repo-type=posix --posix-path=/var/lib/pgbackrest
# Or save plan document for apply:
sudo pgsafe plan --repo-type=posix --posix-path=/var/lib/pgbackrest --json > plan.json

# 3. Apply the plan to converge configuration (idempotent, crash-safe CAS, restarts PostgreSQL)
sudo pgsafe apply plan.json
# Or direct apply:
# sudo pgsafe apply --repo-type=posix --posix-path=/var/lib/pgbackrest

# 4. Take an on-demand backup (exits 1 DEGRADED: backup exists, but recovery assurance requires a drill)
sudo pgsafe backup --type=full

# 5. Run an isolated recovery drill in sandbox to prove bootability (persists trusted evidence, exits 0 SAFE)
sudo pgsafe drill

# 6. Inspect trustworthy recovery status (exits 0 SAFE)
sudo pgsafe status

# 7. Safely restore into a separate target directory (verifies restored cluster on ephemeral port)
sudo pgsafe restore --target /var/lib/postgresql/restored_data

CLI Output & Machine Integration

Every command supports --json (both pgsafe --json <cmd> and pgsafe <cmd> --json):

pgsafe status --json
pgsafe doctor --json
pgsafe backup --json
pgsafe drill --json
pgsafe restore --target /path --json

Exit Codes

Exit codes are command-specific:

Command 0 1 2 3
status / doctor SAFE DEGRADED UNSAFE ERROR
plan Plan ready (not used) Blocked ERROR
apply Converged Execution failure Blocked ERROR
backup SAFE DEGRADED UNSAFE / Refusal ERROR
drill SAFE DEGRADED UNSAFE / Stop fail ERROR
restore Verified & restored (not used) Refusal / Unsafe ERROR

Once command dispatch reaches pgsafe command handling, --json guarantees structured output on stdout. Early Cobra flag parsing errors may produce stderr-only diagnostics and exit 3.

For the complete machine-readable specification, schema shapes, and error codes, see docs/AGENT_CONTRACT.md. For the underlying guarantees and recovery semantics, see docs/RECOVERY_MODEL.md.


License

MIT

Contributors

minibikini

Issues