Skip to content

Commit

Permalink
storage: unify replica addition and removal paths
Browse files Browse the repository at this point in the history
This continues the reworking of the various replication change APIs with
the goal of allowing
a) testing of general atomic replication changes
b) issuing replica swaps from the replicate queue (in 19.2).

For previous steps, see:

#39485
#39611

This change is not a pure plumbing PR. Instead, it unifies
`(*Replica).addReplica` and `(*Replica).removeReplica` into a method
that can do both, `(*Replica).addAndRemoveReplicas`.

Given a slice of ReplicationChanges, this method first adds learner
replicas corresponding to the desired new voters. After having sent
snapshots to all of them, the method issues a configuration change that
atomically
- upgrades all learners to voters
- removes any undesired replicas.

Note that no atomic membership changes are *actually* carried out yet.
This is because the callers of `addAndRemoveReplicas` pass in only a
single change (i.e. an addition or removal), which the method also
verifies.

Three pieces are missing after this PR: First, we need to be able to
instruct raft to carry out atomic configuration changes:

https://github.com/cockroachdb/cockroach/blob/2e8db6ca53c59d3d281e64939f79d937195403d4/pkg/storage/replica_proposal_buf.go#L448-L451

which in particular requires being able to store the ConfState
corresponding to a joint configuration in the unreplicated local state
(under a new key).

Second, we must pass the slice of changes handed to
`AdminChangeReplicas` through to `addAndRemoveReplicas` without
unrolling it first, see:

https://github.com/cockroachdb/cockroach/blob/3b316bac6ef342590ddc68d2989714d6e126371a/pkg/storage/replica_command.go#L870-L891

and

https://github.com/cockroachdb/cockroach/blob/3b316bac6ef342590ddc68d2989714d6e126371a/pkg/storage/replica.go#L1314-L1325

Third, we must to teach the replicate queue to issue the "atomic
swaps"; this is the reason we're introducing atomic membership changes
in the first place.

Release note: None
  • Loading branch information
tbg committed Aug 13, 2019
1 parent 9363d3e commit 06dde3c
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 133 deletions.
23 changes: 23 additions & 0 deletions pkg/roachpb/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,29 @@ func (acrr *AdminChangeReplicasRequest) AddChanges(chgs ...ReplicationChange) {
}
}

// ReplicationChanges is a slice of ReplicationChange.
type ReplicationChanges []ReplicationChange

func (rc ReplicationChanges) byType(typ ReplicaChangeType) []ReplicationChange {
var sl []ReplicationChange
for _, chg := range rc {
if chg.ChangeType == typ {
sl = append(sl, chg)
}
}
return sl
}

// Additions returns a slice of all contained replication changes that add replicas.
func (rc ReplicationChanges) Additions() []ReplicationChange {
return rc.byType(ADD_REPLICA)
}

// Removals returns a slice of all contained replication changes that remove replicas.
func (rc ReplicationChanges) Removals() []ReplicationChange {
return rc.byType(REMOVE_REPLICA)
}

// Changes returns the changes requested by this AdminChangeReplicasRequest, taking
// the deprecated method of doing so into account.
func (acrr *AdminChangeReplicasRequest) Changes() []ReplicationChange {
Expand Down
10 changes: 6 additions & 4 deletions pkg/storage/client_replica_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1673,20 +1673,22 @@ func TestChangeReplicasGeneration(t *testing.T) {
assert.EqualValues(t, repl.Desc().GetGeneration(), oldGeneration+2)

oldGeneration = repl.Desc().GetGeneration()
if _, err := repl.ChangeReplicas(
oldDesc := repl.Desc()
newDesc, err := repl.ChangeReplicas(
context.Background(),
roachpb.REMOVE_REPLICA,
roachpb.ReplicationTarget{
NodeID: mtc.idents[1].NodeID,
StoreID: mtc.idents[1].StoreID,
},
repl.Desc(),
oldDesc,
storagepb.ReasonRangeOverReplicated,
"",
); err != nil {
)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
assert.EqualValues(t, repl.Desc().GetGeneration(), oldGeneration+1)
assert.EqualValues(t, repl.Desc().GetGeneration(), oldGeneration+1, "\nold: %+v\nnew: %+v", oldDesc, newDesc)
}

func TestSystemZoneConfigs(t *testing.T) {
Expand Down
Loading

0 comments on commit 06dde3c

Please sign in to comment.