Zum Inhalt springen
Deutsch

MariaDB

Das MariaDB-Backend ist das Geschwister des Postgres-Backends für Teams auf MariaDB oder MySQL. Es liefert dieselben drei Komponenten — MariaDbJournal, MariaDbSnapshotStore und MariaDbDurableStateStore — gegen eine einzige Datenbank, über den offiziellen mariadb-Connector (der sowohl MariaDB als auch MySQL spricht).

Es ist eine eigenständige Implementierung (kein geteilter Dialekt-Layer), also ist das SQL idiomatisches MariaDB — der öffentliche Vertrag und das Verhalten sind aber identisch.

mariadb ist eine optionale Peer-Dependency:

Terminal-Fenster
bun add mariadb

Beim ersten Zugriff lazy-importiert, wie jeder andere Adapter.

import {
ActorSystem,
PersistenceExtensionId,
registerMariaDbPlugins,
} from 'actor-ts';
const system = new ActorSystem({
name: 'my-app',
config: `
actor-ts.persistence.journal.plugin = "actor-ts.persistence.journal.mariadb"
actor-ts.persistence.snapshot-store.plugin = "actor-ts.persistence.snapshot-store.mariadb"
`,
});
const ext = system.extension(PersistenceExtensionId);
const { durableStateStore } = registerMariaDbPlugins(ext, {
journal: { poolConfig: conn },
snapshotStore: { poolConfig: conn, keepN: 3 },
durableStateStore: { poolConfig: conn },
});
// conn = { host, port: 3306, user, password, database } — oder gib oben
// einen geteilten `pool` (aus mariadb.createPool) mit, um einen Pool über
// alle drei zu nutzen, oder eine Connection-URL via `url`.

Wie bei Postgres werden Journal + Snapshot-Store über die Plugin-IDs ausgewählt, und der Durable-State-Store wird zurückgegeben, damit du ihn in die Settings deines DurableStateActor reichst.

interface MariaDbConnection {
url?: string; // mariadb://user:pass@host:3306/db
poolConfig?: Record<string, unknown>; // { host, port, user, password, database, … }
pool?: MariaDbPoolLike; // vorgebauter / geteilter Pool
}
interface MariaDbJournalOptions extends MariaDbConnection {
eventsTable?: string; tagsTable?: string; autoCreateTables?: boolean;
}
interface MariaDbSnapshotStoreOptions extends MariaDbConnection {
snapshotsTable?: string; keepN?: number; autoCreateTables?: boolean;
}
interface MariaDbDurableStateStoreOptions extends MariaDbConnection {
table?: string; autoCreateTables?: boolean;
}

Diskretes poolConfig (host/user/password/database) ist der portabelste Verbindungsweg; url und ein vorgebauter pool werden ebenfalls akzeptiert.

Gleiche Form wie bei Postgres, mit MariaDB-Typen — VARCHAR(255)-Ids, BIGINT für Sequence/Revision/Timestamp, LONGTEXT-Payloads — und Indizes inline im CREATE TABLE deklariert (portabel über MariaDB-/MySQL-Versionen, anders als CREATE INDEX IF NOT EXISTS):

CREATE TABLE events (
persistence_id VARCHAR(255) NOT NULL,
sequence_nr BIGINT NOT NULL,
payload LONGTEXT NOT NULL,
tags TEXT,
timestamp BIGINT NOT NULL,
PRIMARY KEY (persistence_id, sequence_nr),
INDEX idx_events_pid (persistence_id)
);
-- events_tags, snapshots, durable_state: wie bei Postgres, mit den Typen oben

Das Verhalten ist identisch; das SQL unterscheidet sich:

OperationPostgresMariaDB
Platzhalter$1, $2?
Tag-Dedup-InsertON CONFLICT DO NOTHINGINSERT IGNORE
Snapshot-UpsertON CONFLICT … DO UPDATEON DUPLICATE KEY UPDATE
keepN-PruneNOT IN (SELECT … LIMIT)derived-table-gewrappte Subquery¹
Durable-Create-KonfliktON CONFLICT DO NOTHING → rowCountreines INSERT, ER_DUP_ENTRY (1062) fangen
Concurrency-BackstopSQLSTATE 23505ER_DUP_ENTRY / 1062

¹ MySQL/MariaDB lehnen LIMIT in einer nackten IN (SELECT …) gegen die zu löschende Tabelle ab, daher wrappt der Prune die Subquery in eine Derived Table.

BIGINT kann der Connector als JS-bigint liefern; das Backend coerct Sequence/Revision/Timestamp an der Mapping-Grenze zu number.

  • PostgreSQL — das Geschwister-Backend, mit dem ausführlicheren Durchgang zu Registrierung + Concurrency.
  • Cassandra-Journal — verteilt, für Scale-out.
  • Durable State — die State-orientierte Alternative zum Event Sourcing.