Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CASSANDRA-20449 Serialization can lose complex deletions in a mutation with multiple collections in a row #3987

Open
wants to merge 1 commit into
base: cassandra-5.0
Choose a base branch
from

Conversation

maedhroz
Copy link
Contributor

patch by Caleb Rackliffe; reviewed by ? for CASSANDRA-20449

COLUMN_COMPARATOR, isStatic() ? FIRST_COMPLEX_STATIC : FIRST_COMPLEX_REGULAR, 0L);
return result == Cell.MAX_DELETION_TIME;
return result == Long.MAX_VALUE;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I simply reverted here rather than trying to do something less brittle around the stop value. Open to doing that if we think it really helps...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So when working on 14227 the whole code was littered with magical sentinel values and it was very difficult to make sense of things. I did my best to provide semantic meaning to those with proper constant names and apparently broke this one. Could you name this sthg meaningful?

throw new IllegalStateException("Object " + o + " maps to a buffer that already exists in the set");
// decompose/serializer doesn't use the isMultiCell, so safe to do this
return SetType.getInstance(BytesType.instance, false).decompose(bbs);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is part of a larger set of capabilities already in trunk.

// If the complex deletion is not properly serialized, node 2 will think the update on s2 was an append...
assertRows(CLUSTER.get(2).executeInternal(select), row(0, 0, set(1, 2), set(2), set(1, 2)));
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably needs to be accompanied by proper fuzz testing of the Mutation serialization complex in trunk, where we have better tooling for that.

CC @dcapwell

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to assert roundtrip serialization of Mutations (and add Mutation.equals). I was also thinking we'd be able to find this in one of David's tests that uses a model and runs commands like unsafe bounce (where commit log replay occurs on startup). But we'd have to read across all replicas at NODE_LOCAL to find this, since including a replica with the correct update in the memtable would have hidden the issue.

TopologyMixupTestBase appears to do an unsafe shutdown but HarryTopologyMixupTest doesn't appear to generate mixed set overwrite + set append operations, so we wouldn't find it there as it's currently implemented.

@maedhroz maedhroz force-pushed the CASSANDRA-20449-5.0 branch from 9299e6e to ac9607b Compare March 18, 2025 15:06
{
Set<?> set = (Set<?>) obj;
// convert subtypes to BB
Set<ByteBuffer> bbs = new LinkedHashSet<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can set initial capacity here to match obj?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to make this match what was in trunk...although I agree in principle.

// If the complex deletion is not properly serialized, node 2 will think the update on s2 was an append...
assertRows(CLUSTER.get(2).executeInternal(select), row(0, 0, set(1, 2), set(2), set(1, 2)));
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to assert roundtrip serialization of Mutations (and add Mutation.equals). I was also thinking we'd be able to find this in one of David's tests that uses a model and runs commands like unsafe bounce (where commit log replay occurs on startup). But we'd have to read across all replicas at NODE_LOCAL to find this, since including a replica with the correct update in the memtable would have hidden the issue.

TopologyMixupTestBase appears to do an unsafe shutdown but HarryTopologyMixupTest doesn't appear to generate mixed set overwrite + set append operations, so we wouldn't find it there as it's currently implemented.


// If the complex deletion is not properly serialized, node 2 will think the update on s2 was an append...
assertRows(CLUSTER.get(2).executeInternal(select), row(0, 0, set(1, 2), set(2), set(1, 2)));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed test fails without the changes, passes with 👍

@maedhroz maedhroz requested review from bereng and aratno March 18, 2025 18:02
@@ -1823,7 +1824,7 @@ private static <V> int find(Object[] btree, V from, Comparator<V> comparator)

private static boolean isStopSentinel(long v)
{
return v == Long.MAX_VALUE;
return v == STOP_SENTINEL_VALUE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you update docstring on BTree#accumulate? Also looks like we stopped using the sentinel Long.MIN_VALUE here a while ago, seems like a mistake in the comment.

Not something that should be addressed in this patch, but feels like we should have a separate AbortableLongAccumulator that signals early termination out of band to make this even safer.

@maedhroz maedhroz force-pushed the CASSANDRA-20449-5.0 branch from ac9607b to b856fd4 Compare March 18, 2025 19:04
…collections in a row

patch by Caleb Rackliffe; reviewed by Berenguer Blasi and Abe Ratnofsky for CASSANDRA-20449
@maedhroz maedhroz force-pushed the CASSANDRA-20449-5.0 branch from b856fd4 to 11448dd Compare March 18, 2025 19:06
@bereng
Copy link
Contributor

bereng commented Mar 19, 2025

+1

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.

3 participants