Перейти к содержимому
Русский

Wire-compatible databases

Это содержимое пока не доступно на вашем языке.

Several distributed databases speak the PostgreSQL wire protocol, which means the Postgres backend drives them with no new code:

DatabaseJournalSnapshot storeDurable stateCertified by
CockroachDBtest:integration:cockroachdb
YugabyteDB (YSQL)test:integration:yugabytedb

There is no CockroachJournal and no YugabyteJournal — you use PostgresJournal and point it at the other server:

import { PostgresJournal, PostgresJournalOptions } from 'actor-ts';
// CockroachDB
const cockroachJournalOptions = PostgresJournalOptions.create()
.withUrl('postgres://root@localhost:26257/defaultdb?sslmode=verify-full');
const journal = new PostgresJournal(cockroachJournalOptions);

YugabyteDB serves YSQL on 5433, not 5432:

const yugabyteJournalOptions = PostgresJournalOptions.create()
.withUrl('postgres://yugabyte@localhost:5433/yugabyte');

Everything else — registerPostgresPlugins, the plugin IDs, the options families — is exactly as documented for Postgres.

Why this works, and why it is tested rather than assumed

Section titled “Why this works, and why it is tested rather than assumed”

Wire compatibility gets you the protocol; it does not automatically get you identical semantics. Two things in particular could have broken and did not:

  • Error classification. The journal’s optimistic-concurrency backstop translates a lost write race into JournalConcurrencyError. It matches on SQLSTATE, never on message text — which matters because YugabyteDB is known to reword some Postgres error messages (yugabyte/yugabyte-db#9294). A text-matching implementation would have failed silently there, in the worst possible way: a real conflict surfacing as a generic error.

    Matching the code was necessary but, it turned out, not sufficient. Both engines run at SERIALIZABLE and abort the losing transaction before it reaches the primary key, so they report 40001 (serialization failure) where PostgreSQL reports 23505 (unique violation). The stores classify both, but they do not trust a contention abort on its own: an abort proves only that the engine picked a victim, not that anyone else wrote. So they re-read the head and report a conflict only if it actually moved — otherwise an ordinary lock-wait timeout against an unrelated transaction would be relabelled as someone else’s append and send the caller into a retry loop against a head that is never going to change.

  • The SQL itself. ON CONFLICT … DO UPDATE, GREATEST, CREATE INDEX IF NOT EXISTS and LIMIT inside a subquery are all used by the Postgres stores and all accepted by both servers.

Both suites run the same contract as the Postgres suite — journal append, ranged reads, the compaction high-water mark, tags, snapshot keepN pruning, durable-state CAS, and racing appends — so a future upstream divergence turns a CI job red instead of surfacing in production.

Terminal window
bun run test:integration:cockroachdb
bun run test:integration:yugabytedb

Both need Docker. YugabyteDB initializes its system catalogs on first boot and takes noticeably longer to become ready than any other image in the matrix; the runner waits up to three minutes for it.

  • PostgreSQL — the backend that serves all of these, and the full options reference.
  • Cassandra journal — if you want a distributed store with a native driver rather than the Postgres protocol.
  • Persistence overview — the backend matrix.