db

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package db provides Postgres connection bootstrapping and schema migration for the Wardyn control plane. Postgres is the ONLY required dependency.

Index

Constants

View Source
const GroundTruthRotatorLockKey int64 = 0x5741524459_475452 // ASCII "WARDYGTR"

GroundTruthRotatorLockKey elects the ground-truth token rotator's leader across control planes (S2). Unlike ReaperAdvisoryLockKey (re-tried every tick via TryAdvisoryLock, release()d at the end of each one), this key is acquired ONCE before the rotator's loop starts and held for the process lifetime: only the holder mints/writes the shared token file, and every other replica parks on a backoff and retries, taking over automatically when the holder's Postgres session ends.

It buys AT MOST ONE STEADY-STATE leader, NOT mutual exclusion. An advisory lock dies with its SESSION, not with the process, and the holder never re-verifies it: a Postgres restart, a failover, pg_terminate_backend or an idle-session timeout releases it under a still-running leader, and a standby takes over within one backoff — two rotators, neither aware. Harmless for THIS workload only, because every write is an atomic rename of a stateless token (cmd/wardynd/gt_rotator.go). Work that needs genuine fencing must not reuse this key. Any stable value works, as long as it differs from every other key in this file.

View Source
const ReaperAdvisoryLockKey int64 = 0x5741524459_524541 // ASCII "WARDYREA"

ReaperAdvisoryLockKey makes the lifecycle reap tick single-flight across control planes. Unlike migrateAdvisoryLockKey (a BLOCKING lock — the second boot must still see the migrations applied), this one is only ever taken with TryAdvisoryLock: a replica that loses SKIPS the tick, because a queued second reap of the same runs is pure duplicate work and a duplicate run.autostop.

Variables

This section is empty.

Functions

func AuditDDLProtected

func AuditDDLProtected(ctx context.Context, pool *pgxpool.Pool) (bool, error)

AuditDDLProtected reports whether the given (application) pool's role is UNABLE to bypass the audit_events append-only triggers via DDL — i.e. it is neither a superuser nor a MEMBER of the table's owner role (membership, not just direct ownership: a role GRANTed the owner role inherits DROP TRIGGER / ALTER ... DISABLE TRIGGER rights). The N4 role-separation only protects the append-only guarantee when this is true, so the two-DSN deploy must be VERIFIED here rather than assumed (honesty: never log a protection claim stronger than the enforcing role setup). Fails safe: any ambiguity (missing table, error) reports NOT protected.

func Connect

func Connect(ctx context.Context, dsn string) (*pgxpool.Pool, error)

Connect opens a pgxpool to dsn and performs a lightweight liveness check. Returns the pool; caller owns Close().

func Migrate

func Migrate(ctx context.Context, pool *pgxpool.Pool) error

Migrate applies all migrations in internal/db/migrations/*.sql in lexical order. Each migration runs inside its own transaction; already-applied filenames (tracked in schema_migrations) are skipped. Idempotent.

func TryAdvisoryLock added in v0.5.0

func TryAdvisoryLock(ctx context.Context, pool *pgxpool.Pool, key int64) (release func(), ok bool, err error)

TryAdvisoryLock takes session-level advisory lock key on a connection borrowed from pool WITHOUT waiting, reporting ok=false when another session already holds it. Call the returned release (deferred) to unlock and hand the connection back — skipping it strands a pooled conn for the life of the process. Only for work of BOUNDED duration: the borrowed conn is unavailable to everyone else until release — which also means the caller's own queries need a SECOND conn, so this requires pool_max_conns >= 2 (a 1-conn pool would self-deadlock: the lock holds the only conn while the guarded work blocks on Acquire; the reaper's per-tick deadline turns that into a failed tick, not a hang, but the lock is still wasted).

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL