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 source | Required? | Notes |
|---|---|---|
| PostgreSQL 14+ | Yes | 14–17 tested in CI |
wal_level = logical | Yes | Server-wide; needs a restart. Validated at startup. |
A role with REPLICATION | Yes | Used for the stream and to create the slot |
REPLICA IDENTITY FULL on each captured table | Yes | The PostgreSQL analog of MySQL's binlog_row_image = FULL. Validated per table. |
A PUBLICATION covering those tables | Yes, you create it | dbtrail validates it exists; it does not create it |
| A replication slot | No, created for you | Created on first run, reused on restart |
max_slot_wal_keep_size set (not -1) | Strongly recommended | Left 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:
- Open the console (http://127.0.0.1:8090) and sign in.
- + Add server → set Source type to PostgreSQL. The PostgreSQL-only fields appear: Database, Replication slot, and Publication.
- 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.
- 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.