Skip to content

kvstorage: destroy old replica in CreateUninitializedReplica #171156

Draft
pav-kv wants to merge 3 commits into
cockroachdb:masterfrom
pav-kv:fix-uninit-replica-bug
Draft

kvstorage: destroy old replica in CreateUninitializedReplica #171156
pav-kv wants to merge 3 commits into
cockroachdb:masterfrom
pav-kv:fix-uninit-replica-bug

Conversation

@pav-kv

@pav-kv pav-kv commented May 29, 2026

Copy link
Copy Markdown
Collaborator

Previously, when CreateUninitializedReplica finds an existing replica with an older ReplicaID, it fell through and only overwrote the RaftReplicaID. As a result, the new replica inherited the old replica's HardState.

This is a bug. Fixed by calling DestroyReplica on the old replica, which clears all its state and writes a RangeTombstone. This is the same path used by removeUninitializedReplicaRaftMuLocked.


The previous WAG invariant required each RangeID to appear at most once in a node's event list. This was too strict for operations that encompass multiple lifecycle transitions for the same range, such as destroying an old replica and creating a new one in CreateUninitializedReplica.

Relax the invariant and update canApplyWAGNode to handle multiple events per RangeID. When a RangeID appears more than once, the replay logic now computes the expected post-event state via advance() and uses it to evaluate subsequent events for the same range, instead of re-loading the persisted state.

@trunk-io

trunk-io Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

Merging to master in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@cockroach-teamcity

Copy link
Copy Markdown
Member

This change is Reviewable

@pav-kv pav-kv force-pushed the fix-uninit-replica-bug branch from 803b5b0 to e9d874c Compare May 29, 2026 09:59
pav-kv and others added 3 commits May 29, 2026 11:44
The previous WAG invariant required each RangeID to appear at most once
in a node's event list. This was too strict for operations that
encompass multiple lifecycle transitions for the same range, such as
destroying an old replica and creating a new one in
CreateUninitializedReplica.

Relax the invariant and update canApplyWAGNode to handle multiple events
per RangeID. When a RangeID appears more than once, the replay logic now
computes the expected post-event state via advance() and uses it to
evaluate subsequent events for the same range, instead of re-loading the
persisted state.

Epic: none
Release note: None

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The LoadReplicaState call at the end of CreateUninitializedReplica was a
post-write sanity check that read back the ReplicaMark just written. This
required the caller to provide a read-write batch (so own writes are
visible), and also required passing storeID and raftRO which were only
used by this check.

Remove this verification step. The caller (tryGetOrCreateReplica) already
calls LoadReplicaState separately after committing the batch, so the
check was redundant.

Epic: none
Release note: None

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When CreateUninitializedReplica finds an existing replica with an older
ReplicaID, it must destroy the old replica before creating the new one.
Previously, the code fell through and only overwrote the RaftReplicaID,
leaving behind stale raft state (HardState, raft log) from the old
replica. This could cause a newly created replica to pick up a non-empty
HardState.Commit, violating the uninitialized replica invariant.

Fix this by calling DestroyReplica on the old replica, which clears all
its state and writes a RangeTombstone. This is the same path used by
removeUninitializedReplicaRaftMuLocked.

The function signature changes from taking State to taking a ReadWriter,
since destroying the old replica requires raft write access.

Epic: none
Release note: None

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@pav-kv pav-kv force-pushed the fix-uninit-replica-bug branch from e9d874c to 5190175 Compare May 29, 2026 10:44
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.

2 participants