Skip to content

Multi-process WAL: PrepareTransactionAsync and the direct commit paths bypass the commit and cross-process writer locks #188

Open

Description

@CaffeinatedCoder

Found during the review of #169.

StorageEngine.PrepareTransactionAsync (both overloads) writes Begin and Write records to the WAL without holding _commitLock or, in multi-process mode, the SHM writer lock. A checkpoint's WAL truncation (TryTruncateWalAsync) only excludes writers that hold _commitLock, so it can run between a prepare and the matching commit and drop the prepared transaction's records.

The in-library flow (Transaction.PrepareAsync then CommitAsync) rewrites all pages through group commit, so the commit itself survives today. But the prepared records are not durable the way a 2PC prepare should be, and after such a truncation recovery can't see a prepared-but-uncommitted transaction. Prepare records can also interleave with a group-commit batch in the WAL stream, because only the per-record WAL lock serialises them.

Related: the public direct commit paths CommitTransactionAsync(ulong) and MarkTransactionCommittedAsync(ulong) take _commitLock, but in multi-process mode they do not:

So their records can overwrite another process's records or stay invisible to other processes, and another process's truncation can discard them. Nothing in the library calls them, but they are public.

Possible fix: route prepare and the direct commit paths through the same locked append sequence as ProcessBatchAsync (_commitLock, SHM writer lock, TryCatchUpWithSharedWal, SeekToEnd, append, publish), and keep a prepared transaction's records from being truncated until it commits or aborts. Alternatively, reject these paths when AllowMultiProcessAccess is set.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpackage/coreAffects BLite.Corepriority/P3Backlog / later majorseverity/lowCosmetic, ordering or documentation-level difference

    Type

    No type

    Projects

    • Status
      Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions