The safety contract
What every pgdba session promises before a single query runs.
Every connection pgdba makes — checks, doctor probes, migration preflight — runs under the same contract, applied before any analysis query:
- Read-only transaction (
default_transaction_read_only=on) — the server rejects writes even if pgdba had a bug; nothing depends on pgdba being correct. - Statement timeout (default 30s) — a pathological query cannot wedge the session; the run degrades gracefully instead.
- Connect timeout (default 10s) — a hung host cannot stall the run.
- Version gate — PG 13–17 verified from
server_version_num; anything else refuses with a clear error rather than guessing. - Managed-host detection (RDS and friends) — privilege-sensitive checks adapt or skip instead of erroring.
Why writes are opt-in, always
Advice-only is the default for every command that can write: --apply
executes remediation you approve per action; migration writes only after
preflight passes and you confirm; restore rehearsal is fenced away from
production targets. The tool’s job is to make the safe path the default
path — and to record, in an audit log, every action that did run.
On pooled targets (PgBouncer and friends), session SETs do not survive, so
the contract is re-applied per statement with transaction-scoped SET LOCAL
when pooled = true marks the profile.
Proving a run never wrote
pgdba check --journal appends one line per run to pgdba-audit.jsonl
(state dir, else the current directory): run id, date, redacted target,
executed check ids, statement count and classes, the safety values, and a
writes count from classifying every captured statement (writes:
INSERT/UPDATE/DELETE/MERGE/TRUNCATE/COPY/DDL/GRANT/REVOKE/
COMMENT/CALL/DO; anything unlisted counts as a write). The journal
holds ids and counts only — never query text or secrets — keeps the newest
100 lines, and never changes the run’s exit code. pgdba audit show prints
the trail; a run that applied actions records its applied count alongside,
so applied runs are never misread as zero-write runs.
pgdba self-scan turns the lens on the tool itself: it scans every
generated artifact (reports, journals, history, captured logs) for
DSN/password residue and — with --dsn — runs a scratch check in a temp
directory plus a read-only probe (a temp-table write the server must
refuse; nothing user-visible persists). Exit 0 clean, 1 on residue or a
failed probe, 3 on config/connect errors.