Skip to content
This project is part of pgEdge Labs and is under active development. APIs and features may change without notice.

Companion Reference

This document documents every companion command, flag, and default. The companion is a single binary built from the companion directory.

Building the companion

Build the binary with the Go toolchain, version 1.25 or later:

cd companion
go build -o volvra-companion .

The companion depends on github.com/jackc/pglogrepl and github.com/jackc/pgx/v5. Both declare a minimum of Go 1.25, which sets the floor for the companion. Both are client libraries, so neither imposes anything on the database.

Command summary

The following table describes each command:

Command Purpose
run Stream a replication slot and archive the changes.
verify Re-hash every segment and re-walk the manifest chain.
restore Load an archive back into volvra.change_log.
status Report the durable tier from the database's point of view.
help Print usage.

Common flags

The following table describes the flags every command accepts:

Flag Default Description
--dsn The VOLVRA_DSN environment variable The libpq connection string.
--archive None The archive directory.

Give the connection string as a URL or as keyword and value pairs. Both forms work, because the companion parses the string rather than appending to it.

The companion registers every flag for every command, so a flag that does not apply to a command is accepted and ignored rather than rejected. The tables below group each flag with the command the flag affects.

The run command

run creates the slot if the slot is absent, resumes from the archive, and streams until interrupted:

volvra-companion run --dsn "$DATABASE_URL" \
    --archive /srv/volvra-archive \
    --slot volvra_companion \
    --publication volvra_pub \
    --segment-bytes 67108864 \
    --lag-warn 536870912 \
    --lag-max 5368709120

The following table describes each flag the command accepts:

Flag Default Description
--slot volvra_companion The logical replication slot to read.
--publication volvra_pub The publication to stream.
--segment-bytes 67108864, which is 64 MB Rotate to a new segment once the current one reaches this size.
--lag-warn 536870912, which is 512 MB Log a warning once the slot retains this much write-ahead log.
--lag-max 5368709120, which is 5 GB Advance the slot past this volume and record the skipped range as a gap.

The command requires --dsn and --archive.

How run acknowledges progress

The companion tells PostgreSQL that write-ahead log may be discarded only up to a position the companion has written, flushed, and recorded in the manifest. Acknowledging sooner would let PostgreSQL discard log the archive does not hold.

The archive is therefore the authority on what is durable, rather than the slot. On start, the companion resumes from the last position the archive holds, even when the slot has confirmed a later position.

The verify command

verify checks an archive with no database connection:

volvra-companion verify --archive /srv/volvra-archive

The command prints the archive path, the slot, the segment count, and the change count, then either confirms the archive or lists one finding per problem segment. The command exits non-zero when any finding is present.

The restore command

restore verifies the archive, then loads the changes:

volvra-companion restore --archive /srv/volvra-archive \
    --dsn "$DATABASE_URL"

The following table describes the flag the command adds:

Flag Default Description
--dry-run Off Parse and count without connecting to a database or changing anything.

The command refuses an archive that does not verify. Gap and truncate records carry no row image, so the command reports those as skipped.

Restored rows carry actor set to archive: followed by the log position, and db_user set to archive, so restored history is distinguishable from history the trigger tier captured.

The status command

status reports the durable tier as the database sees it:

volvra-companion status --dsn "$DATABASE_URL"

The command calls volvra.companion_status, so the output matches what that function returns in SQL.

The archive on disk

An archive directory holds a manifest and one file per segment. The following table describes the contents:

Path Contents
manifest.json Archive metadata and one record per sealed segment.
0000000001.ndjson The first segment, one JSON change per line.

The following table describes each field of a segment record in the manifest:

Field Meaning
seq Segment number.
file Segment file name.
start_lsn Log position of the first change in the segment.
end_lsn Log position of the last change in the segment.
changes Number of lines in the segment.
bytes Size of the segment in bytes.
sha256 Hash of the segment content.
prev Chain value of the previous segment.
chain Hash of the previous chain value and this segment's hash.
sealed_at When the companion closed the segment.

The following table describes the top-level manifest fields:

Field Meaning
archive Always the string volvra.
format Archive format version.
slot Replication slot the archive belongs to.
publication Publication the companion streamed.
created_at When the archive was first opened.
segments The array of segment records described above.

The companion refuses to append to an archive whose slot differs from the one given on the command line, so two slots cannot be mixed into one archive.

Change records

The following table describes each field of a change record:

Field Meaning
lsn Log position of the change.
xid Transaction identifier.
commit_ts Commit timestamp of the transaction.
table Schema-qualified table name, with every identifier quoted.
op I for insert, U for update, D for delete, T for truncate.
pk Primary key of the affected row.
old Column values before the change.
new Column values after the change.

A gap record replaces the row fields with the following:

Field Meaning
gap Always true.
from_lsn Start of the range the companion could not archive.
to_lsn End of that range.
reason Why the range is missing.

Exit codes

The following table describes the exit codes:

Code Meaning
0 Success.
1 An error occurred; the message names the cause.
2 The command line was invalid or unrecognized.

Removing a companion

Stop the companion, then drop the slot so the database stops retaining write-ahead log:

SELECT pg_drop_replication_slot('volvra_companion');
DROP PUBLICATION volvra_pub;

Dropping the slot is the important step. A slot with no consumer retains log indefinitely.

Next Steps