Skip to content

DoltLite does not support atomic commits across attached databases #944

Description

@timsehn

DoltLite does not implement SQLite's super-journal protocol for two-phase commit across multiple attached databases. A `COMMIT` that touches two or more ATTACHed doltlite databases is not atomic: a crash between phase-one and phase-two can leave the databases in inconsistent states (one committed, the other not).

What works

  • Single-database commits are atomic and durable.
  • Multi-table commits within a single doltlite database are atomic (they all go through one `chunkStoreCommit`).
  • ATTACHing a stock-SQLite database to a doltlite connection commits the stock side via SQLite's normal pager; the doltlite side commits via the chunk store. Each is atomic on its own.

What doesn't work

  • A transaction that writes to two or more ATTACHed doltlite databases:
    ATTACH 'other.db' AS other;
    BEGIN;
    INSERT INTO main.t VALUES(...);
    INSERT INTO other.t VALUES(...);
    COMMIT;          -- not atomic across main + other

Why

SQLite's atomic-multi-DB protocol uses a super-journal file. `vdbeCommit` in `src/vdbeaux.c` only takes the super-journal path when at least one attached DB reports a journal mode other than WAL or memory, AND when `xCommitPhaseOne` writes the changes to a recoverable journal before `xCommitPhaseTwo` finalizes them.

DoltLite's pager shim reports WAL unconditionally (`shimPagerGetJournalMode` → `PAGER_JOURNALMODE_WAL`), and `prollyBtreeCommitPhaseOne` is a no-op:

  • `src/pager_shim.c` (`shimPagerGetJournalMode`)
  • `src/prolly_btree.c:4509` (`prollyBtreeCommitPhaseOne`)

So the super-journal code path in `vdbeaux.c` is never selected for multi-DB transactions involving doltlite, and the existing phase-two does the full work of writing chunks + refs + fsync, with no rollback escape hatch once the first DB has committed.

Workaround

Do multi-database writes one DB at a time, or accept the cross-DB inconsistency window. `clone`-style use cases that need to ATTACH a remote doltlite db and stream-write to it are unaffected (single attached writer) — see #939.

Out of scope for now

We're explicitly deprioritizing this. Building a real two-phase commit on top of the chunk store + refs design is a non-trivial lift, and there's no live use case pushing for it. Tracking here so we don't forget; we'll come back to it when a user need surfaces or when doltlite hardens up enough that this becomes the next-most-likely correctness embarrassment.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions