Skip to content

posting: rollup commits parent and split KVs in separate transactions, leaving crash windows #9862

Open

Description

@matthewmcneely

Summary

List.Rollup returns the parent posting list plus its split parts as separate KVs, and TxnWriter.Write (posting/writer.go) commits each KV in its own Badger transaction. A crash between those commits can leave on-disk state that the parent doesn't agree with. This has been the case since multi-part posting lists landed (#3105). It isn't new.

Crash windows

The KVs are sorted by key, so the parent (DefaultPrefix) is written before any split key (ByteSplit). Badger replays a strict prefix after a crash, so the parent can survive without the KVs that follow it.

  1. Parent written, new split part not written. The parent at newMinTs+1 references a part with a new startUid that has no version yet. readListPart does a txn.Get at the parent's version, gets key-not-found, and reads of that list fail. This is the more serious case.
  2. Parent written, removed-split tombstones not written. With fix(posting): mark removed split parts for reclamation #9825, rollup writes BitEmptyPosting tombstones for splits the parent no longer references. If the crash lands before those commit, the old split payload stays the latest value for its key. The new parent doesn't list it, so no later rollup will rediscover it and the space leaks indefinitely (same outcome as Orphaned posting-list split parts remain live after deletion, rollup, and compaction #9824, but only on a crash).

Proposed fix

Group the rollup's writes by version instead of committing per KV:

  • Write retained/new split parts at newMinTs first. They're invisible to readers still resolving the old parent, so this is safe on its own.
  • Then commit the parent and all removed-split tombstones in a single transaction at parentVersion (they already share that version).

Keep the distinct timestamps for finite readTs rollups. Collapsing everything to one version would break historical reads at newMinTs.

This needs a TxnWriter API (or a rollup-specific writer) that can commit several KVs in one CommitAt, plus updating the callers in posting/mvcc.go and posting/index.go.

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions