dbtrail

PostgreSQL (Beta)

Capture changes from PostgreSQL, added from the web console, nothing installed in your server

dbtrail captures from PostgreSQL as a first-class source in the web console: + Add server → source type PostgreSQL, same as MySQL. This is a beta capability: capture is type-faithful, REPLICA IDENTITY FULL-enforced, replication-slot/WAL-retention-monitored, and DDL-drift-safe, verified end-to-end against PostgreSQL 14–17 in CI, with documented limitations, notably full-table reconstruct/time-travel, which is GA work.

Nothing is installed in your PostgreSQL server

dbtrail connects as an ordinary logical-replication client using PostgreSQL's built-in pgoutput plugin. It does not install an output plugin, a CREATE EXTENSION, an event trigger, or any other server-side component. You create one publication and set REPLICA IDENTITY; dbtrail reads from it and never writes to your source.

Scope: PostgreSQL is supported as a source (the database you capture changes from). The index (where dbtrail stores the indexed events) stays MySQL (the bundled one from the Compose stack works as-is). Pointing the index at PostgreSQL is not supported.

Prerequisites

Run these once on the source, as a superuser (or the managed-database master user):

On the PostgreSQL sourceRequired?Notes
PostgreSQL 14+Yes14–17 tested in CI
wal_level = logicalYesServer-wide; needs a restart. Validated at startup.
A role with REPLICATIONYesUsed for the stream and to create the slot
REPLICA IDENTITY FULL on each captured tableYesThe PostgreSQL analog of MySQL's binlog_row_image = FULL. Validated per table.
A PUBLICATION covering those tablesYes, you create itdbtrail validates it exists; it does not create it
A replication slotNo, created for youCreated on first run, reused on restart
max_slot_wal_keep_size set (not -1)Strongly recommendedLeft unlimited, a stalled slot pins WAL until the source disk fills. Set a bound (e.g. '10GB').

The exact SQL for each step (including RDS/Aurora, Cloud SQL, and other managed-PostgreSQL variants) is in the repository guide: PostgreSQL source setup and Managed PostgreSQL.

Add it from the console

If you brought up the Compose stack you already have everything:

  1. Open the console (http://127.0.0.1:8090) and sign in.
  2. + Add server → set Source type to PostgreSQL. The PostgreSQL-only fields appear: Database, Replication slot, and Publication.
  3. Fill in host, port, user, password, the database, the slot name (created for you on first run), and the publication you created above. Optionally restrict Schemas.
  4. Save. dbtrail provisions a dedicated index for that source and starts capturing in-process. The console runs the full PostgreSQL preflight (wal_level, publication coverage, REPLICA IDENTITY FULL, slot health) and surfaces any failure as a remediation card. Capture resumes automatically on restart.

The source type is fixed once saved. To change a server's capture engine, delete and re-create it.

What the console shows for PostgreSQL

  • Stream cursor as an LSN: a PostgreSQL stream is labeled "PostgreSQL · logical replication" and shows its position as an LSN instead of a binlog file/position/GTID.
  • Replication-health panel: the Status page shows the slot's WAL-retention state (retained WAL, the safe margin before invalidation) and whether every published table is at REPLICA IDENTITY FULL, with a freshness indicator (a stale snapshot degrades visibly rather than reading as live-healthy).
  • Permanent-loss badge: an invalidated/lost replication slot is surfaced durably: the index is valid only up to that point and capture must be re-baselined to resume.
  • Forensics note: PostgreSQL logical replication carries no backend connection id, so who-changed attribution is unavailable upstream; the Events page says so rather than leaving an unexplained gap.

Recovery and time-travel

Everything downstream of capture works the same as MySQL, because the index is the same: browse events, generate dry-run recovery SQL from the Recover tab, and reconstruct a single row at a point in time from the Time-travel tab (with a baseline configured).

You can also run AS OF queries against historical state directly from psql, over the PostgreSQL wire protocol:

SELECT * FROM _flashback.orders AS OF '5 minutes ago' WHERE id = 42;

See time-travel over the wire for setup.

Beta limitations: most notably, full-table reconstruct/time-travel is deferred to GA (single-row works), and sequences need a nudge after recovery. The complete list: beta limitations.

Headless / CLI deployments

PostgreSQL capture also ships as a standalone binary, bintrail-pg (Docker image, .deb/.rpm, or from source), carrying the capture command plus the shared read/recovery commands. Full reference: docs/postgres.md.

On this page