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 14, 2019
1 parent 5ec04bc commit 329d825
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 125 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) []ReplicationTarget {
var sl []ReplicationTarget
for _, chg := range rc {
if chg.ChangeType == typ {
sl = append(sl, chg.Target)
}
}
return sl
}

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

// Removals returns a slice of all contained replication changes that remove replicas.
func (rc ReplicationChanges) Removals() []ReplicationTarget {
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 329d825

Please sign in to comment.