Skip to content

CASSANDRA-21333 Decode historical live complex deletions without erasing tombstones - #5144

Open
cheeeee wants to merge 1 commit into
apache:trunkfrom
cheeeee:CASSANDRA-21333-v2-trunk
Open

CASSANDRA-21333 Decode historical live complex deletions without erasing tombstones#5144
cheeeee wants to merge 1 commit into
apache:trunkfrom
cheeeee:CASSANDRA-21333-v2-trunk

Conversation

@cheeeee

@cheeeee cheeeee commented Sep 10, 2026

Copy link
Copy Markdown

CASSANDRA-21333: a row with several complex columns of which only some are updated stores
DeletionTime.LIVE as the complex deletion of the untouched ones. LIVE's local deletion time is the
reserved unsigned value 0xFFFFFFFF; writing it as a delta from the header's minLocalDeletionTime
truncates to int, and reading the delta back sign-extends, so the decoded value is no longer LIVE but
a deletion at Long.MIN_VALUE with an invalid local deletion time. With corrupted_tombstone_strategy
set to exception such an SSTable fails to read.

Change (SerializationHeader): after reading a deletion time, if the timestamp is Long.MIN_VALUE and the
low 32 bits of the local deletion time are the reserved LIVE value, return DeletionTime.LIVE (both the
allocating and the reusable read paths). The timestamp alone is not used as the discriminator because
Long.MIN_VALUE is an acceptable timestamp for a real tombstone, and such tombstones must survive a
round trip. The on-disk encoding is unchanged, so SSTables written by existing versions decode to LIVE
without a format bump, and no new bytes need to be understood by older readers.
localDeletionTimeSerializedSize now casts to int the same way writeLocalDeletionTime does, so the
computed size matches the bytes written.

Testing (SerializationHeaderTest):

  • testHistoricalLiveDeletionTimeEncoding: the exact byte sequence produced for LIVE by the existing
    writer decodes to DeletionTime.LIVE.
  • testMinimumTimestampTombstoneIsNotLive: a valid tombstone with timestamp Long.MIN_VALUE, LIVE and the
    tombstone again round-trip unchanged, and the serialized size equals the bytes written.
  • testMixedComplexDeletionsInSSTable: a row with a live and a deleted complex column written to and
    read back from a real SSTable, through the cursor read path, yields LIVE for the untouched column.
  • All three fail without the change: the LIVE bytes decode to
    deletedAt=Long.MIN_VALUE, localDeletion=4294967294.

CASSANDRA-21333

Preserve historical writer bytes and recognize LIVE using both its minimum
timestamp and reserved local-deletion-time representation. Keep valid
minimum-timestamp tombstones distinct and match size calculation to the
writer's integer delta encoding.

CASSANDRA-21333

Generated-by: Claude (Anthropic)
@cheeeee
cheeeee force-pushed the CASSANDRA-21333-v2-trunk branch from 0259300 to 624839b Compare September 11, 2026 22:51
@cheeeee cheeeee changed the title CASSANDRA-21333: Write zero delta when localDeletionTime overflows an int CASSANDRA-21333 Decode historical live complex deletions without erasing tombstones Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant