CASSANDRA-21537: Serialize local metadata proposals so concurrent schema changes do not exhaust their retry budge - #4970
Open
pmcfadin wants to merge 1 commit into
Open
Conversation
…t exhaust their retry budget contending for the same epoch Concurrent CQL DDL submitted to a CMS member could fail with a SERVER_ERROR while the request deadline still had seconds remaining. Every concurrent commit read the same highest consecutive epoch and proposed at epoch+1, so all but one loser per round burned a retry attempt, backed off and refetched the log before recomputing. With the attempt limit from the default cms_retry_delay that budget was exhausted long before request_timeout, so valid statements were rejected while several seconds of their deadline remained. Since tryCommitOne can only ever apply one proposal per epoch, and Paxos already takes a per-partition coordinator lock for the duration of the CAS, racing that slot from many local request threads cannot increase throughput; it only converts would-be waiting into wasted attempts. AbstractLocalProcessor now serialises the read-execute-propose cycle for locally originating commits behind a fair lock whose acquisition is bounded by the caller's own deadline. The lock is released before the follower wait, the backoff sleep and any log fetch, so none of those block another proposer. A request which cannot be admitted in time reports that distinctly, and only claims that nothing was proposed when no earlier iteration had reached the CAS, since a lost epoch and an ambiguous Paxos result are indistinguishable to the caller. This does not address races between separate CMS members, which remain the distributed log's responsibility. Admission is FIFO and does not prioritise by transformation kind, so a topology change can queue behind schema DDL which arrived first. patch by Patrick McFadin; reviewed by TBD for CASSANDRA-21537 Assisted-by: Claude Opus 5 <noreply@anthropic.com>
pmcfadin
force-pushed
the
pmcfadin/CASSANDRA-21537/trunk
branch
from
July 28, 2026 04:15
7a8b994 to
b029c7b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Details, reproduction and measurements: CASSANDRA-21537
Concurrent CQL DDL against a CMS member fails with
Could not perform commit after 12 attempts. Time remaining: 4231ms— the retry attempt cap is reached while the request deadline still has seconds left. Every concurrent commit reads the same highest consecutive epoch and proposes atepoch+1, so all but one loser per round burns an attempt, backs off, and refetches the log before recomputing.Fix
AbstractLocalProcessorserialises the read → execute → propose cycle for locally originating commits behind a fairReentrantLock.Retrydeadline, so queue time is charged to the waiter and never extends another request.finallythat unlocks exactly once.Why this shouldn't regress
Paxos.casalready takes a per-partition coordinator lock forthe whole CAS, so local contenders were already serialising — just bounded by
cas_contention_timeoutinstead of the caller's deadline, andonly discoverable by burning an attempt.
tryCommitOnecan only apply one proposal per epoch, so racing that slot locally never added throughput.CMSShutdownTest,DistributedLogTest,LostCommitReqResTest,RetryTest,AlterTopologyTest,CommitStartupByNonCMSNodeTest,ConcurrentSchemaCommitTest,AbstractLocalProcessorLockTest, plusant checkstyle checkstyle-test rat-check.Tests added
ConcurrentSchemaCommitTest(in-JVM) — asserts every submitted statement succeeds and swallows no exception.AbstractLocalProcessorLockTest(unit, ~2s, no sleeps) — timeout while queued, interrupt while queued, andproposal-attempted-then-denied-readmission.
For reviewers
Transformation.Kindpriority, so a topology change can queue behind earlier schema DDL. Happy to add priority if wanted.trunk;cassandra-6.0is equally affected and the TCM source is identical between thempatch by Patrick McFadin; reviewed by TBD for CASSANDRA-21537
Assisted-by: Claude Opus 5