Skip to content

CommandChanges.shouldCleanup short-circuits to NO if there is no data…#4873

Open
belliottsmith wants to merge 15 commits into
apache:trunkfrom
belliottsmith:consistent-expunge
Open

CommandChanges.shouldCleanup short-circuits to NO if there is no data…#4873
belliottsmith wants to merge 15 commits into
apache:trunkfrom
belliottsmith:consistent-expunge

Conversation

@belliottsmith

Copy link
Copy Markdown
Contributor

…, but this is incorrect as Cleanup.EXPUNGE may have dropped the data and the record must receive cleanup EXPUNGE and be reported as ERASED. This can lead to lienarizability violations.

Thanks for sending a pull request! Here are some tips if you're new here:

  • Ensure you have added or run the appropriate tests for your PR.
  • Be sure to keep the PR description updated to reflect all changes.
  • Write your PR title to summarize what this PR proposes.
  • If possible, provide a concise example to reproduce the issue for a faster review.
  • Read our contributor guidelines
  • If you're making a documentation change, see our guide to documentation contribution

Commit messages should follow the following format:

<One sentence description, usually Jira title or CHANGES.txt summary>

<Optional lengthier description (context on patch)>

patch by <Authors>; reviewed by <Reviewers> for CASSANDRA-#####

Co-authored-by: Name1 <email1>
Co-authored-by: Name2 <email2>

The Cassandra Jira

@alanwang67

Copy link
Copy Markdown
Contributor

+1

@ifesdjeen ifesdjeen requested review from Copilot and ifesdjeen June 11, 2026 13:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to prevent Accord journal cleanup/expunge decisions from being surfaced as NotDefined on the load path (which the PR description notes can cause linearizability violations). The visible changes in this repo primarily add/adjust tests and test utilities to reproduce and guard the behavior.

Changes:

  • Add a new regression unit test (AccordExpungeTest) covering Cleanup.EXPUNGE interactions with CommandChanges reconstruction and journal.loadCommand.
  • Extend AccordGenerators.commandsBuilder() with an overload to allow custom TxnId generation (used by the new test).
  • Adjust distributed burn-test behavior and minor test cleanup/comment removals.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/unit/org/apache/cassandra/utils/AccordGenerators.java Adds an overload to build commands with a caller-supplied TxnId generator.
test/unit/org/apache/cassandra/service/accord/AccordExpungeTest.java New regression test exercising EXPUNGE → loadCommand behavior across journal states.
test/distributed/org/apache/cassandra/service/accord/journal/AccordJournalBurnTest.java Sets a global burn-test tuning parameter (CMD_BASE_CHECK_CHANCE) via static initializer.
test/distributed/org/apache/cassandra/service/accord/AccordJournalCompactionTest.java Minor whitespace-only change.
test/distributed/org/apache/cassandra/distributed/test/accord/AccordLoadTest.java Removes commented-out config lines.
.gitmodules Points the modules/accord submodule at a personal fork/branch instead of the canonical Apache repo.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .gitmodules
@belliottsmith belliottsmith force-pushed the consistent-expunge branch 9 times, most recently from f021f32 to 00714e8 Compare June 14, 2026 17:46
…, but this is incorrect as Cleanup.EXPUNGE may have dropped the data and the record must receive cleanup EXPUNGE and be reported as ERASED. This can lead to lienarizability violations.
 - system_accord_debug.executors has wrong clustering type
 - RemoteToLocalVirtualTable should lazily allocate the partition collector to avoid LIMIT clause filtering removing it before it's populated
 - Ensure ReadCoordinator callbacks are invoked on owning thread
{
if (cell.column().isSimple())
return new BTreeRow(clustering, BTree.singleton(cell), minDeletionTime(cell));
return new BTreeRow(clustering, primaryKeyLivenessInfo, Deletion.LIVE, BTree.singleton(cell), minDeletionTime(cell));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we want to do

long minDeletionTime = Math.min(minDeletionTime(primaryKeyLivenessInfo), minDeletionTime(deletion.time()));

as we do in create above here too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch

Future<?> future = toFuture(AsyncResults.reduce(results, Reduce.toNull()));
long timeoutSeconds = getAccord().execute_waiting_on_start_timeout.toSeconds();
if (timeoutSeconds <= 0) future.awaitUninterruptibly().rethrowIfFailed();
else if (!future.awaitUninterruptibly(timeoutSeconds, SECONDS))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we would throw here only on timeout, but not on failure; should we add future.isSuccess() too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Weird, I thought I already handled that. Thanks!

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.

4 participants