Skip to content

bug: row-address mask cache can serve a previous dataset's allow-list at the same URI #9079

Description

@LuciferYang

RowAddrMaskKey is scoped by {version, restrict_hash}, but the metadata cache it lives in is namespaced by dataset URI alone. A dataset dropped and recreated at the same URI restarts its version history at 1, so a long-lived session can serve the new incarnation the previous incarnation's cached stable-row-id allow-list. Stable row ids restart near 0 in both generations, so every row beyond the old generation's id range silently disappears from every indexed query. No error, no warning, just missing rows.

The sibling key RowIdIndexKey already carries the manifest e-tag for exactly this reason, and RowIdSequenceKey is content-addressed. Only the mask key was left without a generation token.

Reproducer, with one shared Session across both incarnations:

  1. Write 10 rows with enable_stable_row_ids: true, then delete("x = 9"). The dataset reaches version 2 and the mask cache holds the allow-list {0..8}.
  2. Drop the dataset directory.
  3. Write 20 rows at the same URI, again with stable row ids, then delete("x = 19"). This incarnation also reaches version 2.
  4. Ask for the deletion mask. It comes back as {0..8} instead of {0..18}, so ids 9 through 18 are treated as deleted.

Reproduced on main at ebba5814c.

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions