Skip to content

Commit 9d2b6d9

Browse files
craig[bot]sumeerbhola
andcommitted
Merge #157960
157960: mma: cleanup the GC time handling r=tbg a=sumeerbhola Instead of having two different ways of computing the GC time, one for undoable changes, and one for no-rollback changes, they are unified and tracked in pendingReplicaChange.gcTime. This also allows us to assign a undo based GC time at the time the change is created, and fix a long standing desire to have a shorter GC duration for lease transfers. Informs #157049 Epic: CRDB-55052 Release note: None Co-authored-by: sumeerbhola <[email protected]>
2 parents 654a5bf + adc10e2 commit 9d2b6d9

File tree

9 files changed

+105
-97
lines changed

9 files changed

+105
-97
lines changed

pkg/kv/kvserver/allocator/mmaprototype/cluster_state.go

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,8 @@ func mapReplicaTypeToVoterOrNonVoter(rType roachpb.ReplicaType) roachpb.ReplicaT
470470
//
471471
// Some the state inside each *pendingReplicaChange is mutable at arbitrary
472472
// points in time by the code inside this package (with the relevant locking,
473-
// of course). Currently, this state is revisedGCTime, enactedAtTime. Neither
474-
// of it is read by the public methods on PendingRangeChange.
473+
// of course). Currently, this state is gcTime, enactedAtTime. Neither of it
474+
// is read by the public methods on PendingRangeChange.
475475
//
476476
// TODO(sumeer): when we expand the set of mutable fields, make a deep copy.
477477
type PendingRangeChange struct {
@@ -714,29 +714,23 @@ func (prc PendingRangeChange) LeaseTransferFrom() roachpb.StoreID {
714714
// change. It may not be enacted if it will cause some invariant (like the
715715
// number of replicas, or having a leaseholder) to be violated. If not
716716
// enacted, the allocator will either be told about the lack of enactment, or
717-
// will eventually expire from the allocator's state after
718-
// pendingChangeGCDuration or revisedGCTime. Such expiration without enactment
719-
// should be rare. pendingReplicaChanges can be paired, when a range is being
720-
// moved from one store to another -- that pairing is not captured here, and
721-
// captured in the changes suggested by the allocator to the external entity.
717+
// will eventually expire from the allocator's state at gcTime. Such
718+
// expiration without enactment should be rare. pendingReplicaChanges can be
719+
// paired, when a range is being moved from one store to another -- that
720+
// pairing is not captured here, and captured in the changes suggested by the
721+
// allocator to the external entity.
722722
type pendingReplicaChange struct {
723723
changeID
724724
ReplicaChange
725725

726726
// The wall time at which this pending change was initiated. Used for
727-
// expiry.
727+
// expiry. All replica changes in a PendingRangeChange have the same
728+
// startTime.
728729
startTime time.Time
729-
// revisedGCTime is optionally populated (the zero value represents no
730-
// revision). When populated, it represents a time, which, if earlier than
731-
// the GC time decided by startTime + pendingChangeGCDuration, will cause an
732-
// earlier GC. It is used to hasten GC (for the remaining changes) when some
733-
// subset of changes corresponding to the same complex change have been
734-
// observed to be enacted.
735-
//
736-
// The GC of these changes happens on a different path than the usual GC,
737-
// which can undo the changes -- this GC happens only when processing a
738-
// RangeMsg from the leaseholder.
739-
revisedGCTime time.Time
730+
// gcTime represents a time when the unenacted change should be GC'd, either
731+
// using the normal GC undo path, or if rangeState.pendingChangeNoRollback
732+
// is true, when processing a RangeMsg from the leaseholder.
733+
gcTime time.Time
740734

741735
// TODO(kvoli,sumeerbhola): Consider adopting an explicit expiration time,
742736
// after which the change is considered to have been rejected. This would
@@ -1100,7 +1094,7 @@ type rangeState struct {
11001094
// - The pending change failed to apply via
11011095
// AdjustPendingChangesDisposition(failed)).
11021096
// - The pending change is garbage collected after this pending change has
1103-
// been created for pendingChangeGCDuration.
1097+
// been created for pending{Replica,Lease}ChangeGCDuration.
11041098
//
11051099
// 3. Dropped due to incompatibility: mma creates these pending changes while
11061100
// working with an earlier authoritative leaseholder message. These changes
@@ -1550,20 +1544,25 @@ func (cs *clusterState) processStoreLeaseholderMsgInternal(
15501544
// Note that normal GC will not GC these, since normal GC needs to undo,
15511545
// and we are not allowed to undo these.
15521546
if len(remainingChanges) > 0 {
1553-
startTime := remainingChanges[0].startTime
1554-
revisedGCTime := remainingChanges[0].revisedGCTime
1555-
if startTime.Add(pendingChangeGCDuration).Before(now) || revisedGCTime.Before(now) {
1547+
gcTime := remainingChanges[0].gcTime
1548+
if gcTime.Before(now) {
15561549
gcRemainingChanges = true
15571550
}
15581551
}
1559-
} else if len(enactedChanges) > 0 {
1560-
// First time this set of changes is seeing something enacted.
1552+
} else if len(enactedChanges) > 0 && len(remainingChanges) > 0 {
1553+
// First time this set of changes is seeing something enacted, and there
1554+
// are remaining changes.
15611555
//
15621556
// No longer permitted to rollback.
15631557
rs.pendingChangeNoRollback = true
1564-
for _, change := range remainingChanges {
1565-
// Potentially shorten when the GC happens.
1566-
change.revisedGCTime = now.Add(partiallyEnactedGCDuration)
1558+
// All remaining changes have the same gcTime.
1559+
curGCTime := remainingChanges[0].gcTime
1560+
revisedGCTime := now.Add(partiallyEnactedGCDuration)
1561+
if revisedGCTime.Before(curGCTime) {
1562+
// Shorten when the GC happens.
1563+
for _, change := range remainingChanges {
1564+
change.gcTime = revisedGCTime
1565+
}
15671566
}
15681567
}
15691568
// rs.pendingChanges is the union of remainingChanges and enactedChanges.
@@ -1865,17 +1864,21 @@ func (cs *clusterState) processStoreLeaseholderMsgInternal(
18651864

18661865
}
18671866

1868-
// If the pending change does not happen within this GC duration, we
1867+
// If the pending replica change does not happen within this GC duration, we
18691868
// forget it in the data-structure.
1870-
const pendingChangeGCDuration = 5 * time.Minute
1869+
const pendingReplicaChangeGCDuration = 5 * time.Minute
1870+
1871+
// If the pending lease transfer does not happen within this GC duration, we
1872+
// forget it in the data-structure.
1873+
const pendingLeaseTransferGCDuration = 1 * time.Minute
18711874

18721875
// partiallyEnactedGCDuration is the duration after which a pending change is
18731876
// GC'd if some other change that was part of the same decision has been
18741877
// enacted, and this duration has elapsed since that enactment. This is
1875-
// shorter than the normal pendingChangeGCDuration, since we want to clean up
1876-
// such partially enacted changes faster. Long-running decisions are those
1877-
// that involve a new range snapshot being sent, and that is the first change
1878-
// that is seen as enacted. Subsequent ones should be fast.
1878+
// shorter than the normal pendingReplicaChangeGCDuration, since we want to
1879+
// clean up such partially enacted changes faster. Long-running decisions are
1880+
// those that involve a new range snapshot being sent, and that is the first
1881+
// change that is seen as enacted. Subsequent ones should be fast.
18791882
const partiallyEnactedGCDuration = 30 * time.Second
18801883

18811884
// Called periodically by allocator.
@@ -1904,11 +1907,8 @@ func (cs *clusterState) gcPendingChanges(now time.Time) {
19041907
if len(rs.pendingChanges) == 0 {
19051908
panic(errors.AssertionFailedf("no pending changes in range %v", rangeID))
19061909
}
1907-
startTime := rs.pendingChanges[0].startTime
1908-
// NB: we don't bother looking at revisedGCTime, since in that case
1909-
// rangeState.pendingChangeNoRollback is set to true, so we can't do GC
1910-
// here (since it requires undo).
1911-
if !startTime.Add(pendingChangeGCDuration).Before(now) {
1910+
gcTime := rs.pendingChanges[0].gcTime
1911+
if !gcTime.Before(now) {
19121912
continue
19131913
}
19141914
if err := cs.preCheckOnUndoReplicaChanges(PendingRangeChange{
@@ -2013,6 +2013,11 @@ func (cs *clusterState) addPendingRangeChange(change PendingRangeChange) {
20132013
// NB: rs != nil is also required, but we also check that in a method called
20142014
// below.
20152015

2016+
gcDuration := pendingReplicaChangeGCDuration
2017+
if change.IsTransferLease() {
2018+
// Only the lease is being transferred.
2019+
gcDuration = pendingLeaseTransferGCDuration
2020+
}
20162021
pendingChanges := change.pendingReplicaChanges
20172022
now := cs.ts.Now()
20182023
for _, pendingChange := range pendingChanges {
@@ -2021,6 +2026,7 @@ func (cs *clusterState) addPendingRangeChange(change PendingRangeChange) {
20212026
cid := cs.changeSeqGen
20222027
pendingChange.changeID = cid
20232028
pendingChange.startTime = now
2029+
pendingChange.gcTime = now.Add(gcDuration)
20242030
pendingChange.enactedAtTime = time.Time{}
20252031
storeState := cs.stores[pendingChange.target.StoreID]
20262032
rangeState := cs.ranges[rangeID]

pkg/kv/kvserver/allocator/mmaprototype/cluster_state_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,9 @@ func printPendingChangesTest(changes []*pendingReplicaChange) string {
245245
var buf strings.Builder
246246
fmt.Fprintf(&buf, "pending(%d)", len(changes))
247247
for _, change := range changes {
248-
fmt.Fprintf(&buf, "\nchange-id=%d store-id=%v node-id=%v range-id=%v load-delta=%v start=%v",
248+
fmt.Fprintf(&buf, "\nchange-id=%d store-id=%v node-id=%v range-id=%v load-delta=%v start=%v gc=%v",
249249
change.changeID, change.target.StoreID, change.target.NodeID, change.rangeID,
250-
change.loadDelta, change.startTime.Sub(testingBaseTime),
250+
change.loadDelta, change.startTime.Sub(testingBaseTime), change.gcTime.Sub(testingBaseTime),
251251
)
252252
if !(change.enactedAtTime == time.Time{}) {
253253
fmt.Fprintf(&buf, " enacted=%v",

pkg/kv/kvserver/allocator/mmaprototype/testdata/cluster_state/rebalance_replica

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ make-pending-changes range-id=1
5757
rebalance-replica: remove-store-id=1 add-store-id=2
5858
----
5959
pending(2)
60-
change-id=1 store-id=2 node-id=2 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s
60+
change-id=1 store-id=2 node-id=2 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s gc=5m0s
6161
prev=(replica-id=none type=VOTER_FULL)
6262
next=(replica-id=unknown type=VOTER_FULL leaseholder=true)
63-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s
63+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=5m0s
6464
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
6565
next=(replica-id=none type=VOTER_FULL)
6666

@@ -98,10 +98,10 @@ store-id=1
9898
get-pending-changes
9999
----
100100
pending(2)
101-
change-id=1 store-id=2 node-id=2 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s
101+
change-id=1 store-id=2 node-id=2 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s gc=5m0s
102102
prev=(replica-id=none type=VOTER_FULL)
103103
next=(replica-id=unknown type=VOTER_FULL leaseholder=true)
104-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s
104+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=5m0s
105105
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
106106
next=(replica-id=none type=VOTER_FULL)
107107

@@ -119,10 +119,10 @@ store-id=1
119119
get-pending-changes
120120
----
121121
pending(2)
122-
change-id=1 store-id=2 node-id=2 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s enacted=5s
122+
change-id=1 store-id=2 node-id=2 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s gc=5m0s enacted=5s
123123
prev=(replica-id=none type=VOTER_FULL)
124124
next=(replica-id=unknown type=VOTER_FULL leaseholder=true)
125-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s enacted=5s
125+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=5m0s enacted=5s
126126
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
127127
next=(replica-id=none type=VOTER_FULL)
128128

@@ -159,10 +159,10 @@ store-id=2 node-id=2 status=ok accepting all reported=[cpu:80, write-bandwidth:8
159159
get-pending-changes
160160
----
161161
pending(2)
162-
change-id=1 store-id=2 node-id=2 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s enacted=5s
162+
change-id=1 store-id=2 node-id=2 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s gc=5m0s enacted=5s
163163
prev=(replica-id=none type=VOTER_FULL)
164164
next=(replica-id=unknown type=VOTER_FULL leaseholder=true)
165-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s enacted=5s
165+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=5m0s enacted=5s
166166
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
167167
next=(replica-id=none type=VOTER_FULL)
168168

pkg/kv/kvserver/allocator/mmaprototype/testdata/cluster_state/rebalance_replica_local_stores

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ make-pending-changes range-id=1
6565
rebalance-replica: remove-store-id=1 add-store-id=2
6666
----
6767
pending(2)
68-
change-id=1 store-id=2 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s
68+
change-id=1 store-id=2 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s gc=5m0s
6969
prev=(replica-id=none type=VOTER_FULL)
7070
next=(replica-id=unknown type=VOTER_FULL leaseholder=true)
71-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s
71+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=5m0s
7272
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
7373
next=(replica-id=none type=VOTER_FULL)
7474

@@ -103,10 +103,10 @@ store-id=1
103103
get-pending-changes
104104
----
105105
pending(2)
106-
change-id=1 store-id=2 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s
106+
change-id=1 store-id=2 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s gc=5m0s
107107
prev=(replica-id=none type=VOTER_FULL)
108108
next=(replica-id=unknown type=VOTER_FULL leaseholder=true)
109-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s
109+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=5m0s
110110
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
111111
next=(replica-id=none type=VOTER_FULL)
112112

@@ -125,14 +125,15 @@ range-id=1 local-store=2 load=[cpu:80, write-bandwidth:80, byte-size:80] raft-cp
125125
store-id=2 replica-id=2 type=VOTER_FULL leaseholder=true
126126

127127
# The addition of replica and lease on s2 is considered enacted. The removal
128-
# of replica and lease from s1 is not yet enacted.
128+
# of replica and lease from s1 is not yet enacted. The gc time is changes to
129+
# be 30s after the enactment.
129130
get-pending-changes
130131
----
131132
pending(2)
132-
change-id=1 store-id=2 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s enacted=5s
133+
change-id=1 store-id=2 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s gc=5m0s enacted=5s
133134
prev=(replica-id=none type=VOTER_FULL)
134135
next=(replica-id=unknown type=VOTER_FULL leaseholder=true)
135-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s
136+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=35s
136137
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
137138
next=(replica-id=none type=VOTER_FULL)
138139

@@ -144,21 +145,21 @@ t=10s
144145
reject-pending-changes change-ids=(1) expect-panic
145146
----
146147
pending(2)
147-
change-id=1 store-id=2 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s enacted=5s
148+
change-id=1 store-id=2 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s gc=5m0s enacted=5s
148149
prev=(replica-id=none type=VOTER_FULL)
149150
next=(replica-id=unknown type=VOTER_FULL leaseholder=true)
150-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s
151+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=35s
151152
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
152153
next=(replica-id=none type=VOTER_FULL)
153154

154155
# Change 2 is found, but is no-rollback, so can't be rejected.
155156
reject-pending-changes change-ids=(2) expect-panic
156157
----
157158
pending(2)
158-
change-id=1 store-id=2 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s enacted=5s
159+
change-id=1 store-id=2 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=0s gc=5m0s enacted=5s
159160
prev=(replica-id=none type=VOTER_FULL)
160161
next=(replica-id=unknown type=VOTER_FULL leaseholder=true)
161-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s
162+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=35s
162163
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
163164
next=(replica-id=none type=VOTER_FULL)
164165

@@ -186,7 +187,7 @@ store-load-msg
186187
get-pending-changes
187188
----
188189
pending(1)
189-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s
190+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=35s
190191
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
191192
next=(replica-id=none type=VOTER_FULL)
192193

@@ -199,17 +200,17 @@ store-id=1 node-id=1 status=ok accepting all reported=[cpu:80, write-bandwidth:8
199200
store-id=2 node-id=1 status=ok accepting all reported=[cpu:80, write-bandwidth:80, byte-size:80] adjusted=[cpu:80, write-bandwidth:80, byte-size:80] node-reported-cpu=160 node-adjusted-cpu=80 seq=4
200201
top-k-ranges (local-store-id=2) dim=ByteSize: r1
201202

202-
# Advance time enough for change 2 to be eligible for GC.
203+
# Advance time enough for change 2 to be eligible for undo GC.
203204
tick seconds=300
204205
----
205206
t=5m10s
206207

207-
# Even after the GC time has elapsed change 2 cannot be undone since it is
208-
# no-rollback.
208+
# Even after the undo based GC time has elapsed change 2 cannot be undone
209+
# since it is no-rollback.
209210
gc-pending-changes
210211
----
211212
pending(1)
212-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s
213+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=35s
213214
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
214215
next=(replica-id=none type=VOTER_FULL)
215216

@@ -224,7 +225,7 @@ store-id=2
224225
get-pending-changes
225226
----
226227
pending(1)
227-
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s enacted=5m10s
228+
change-id=2 store-id=1 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=0s gc=35s enacted=5m10s
228229
prev=(replica-id=1 type=VOTER_FULL leaseholder=true)
229230
next=(replica-id=none type=VOTER_FULL)
230231

@@ -274,10 +275,10 @@ make-pending-changes range-id=1
274275
rebalance-replica: remove-store-id=2 add-store-id=1
275276
----
276277
pending(2)
277-
change-id=3 store-id=1 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=5m30s
278+
change-id=3 store-id=1 node-id=1 range-id=1 load-delta=[cpu:88, write-bandwidth:88, byte-size:88] start=5m30s gc=10m30s
278279
prev=(replica-id=none type=VOTER_FULL)
279280
next=(replica-id=unknown type=VOTER_FULL leaseholder=true)
280-
change-id=4 store-id=2 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=5m30s
281+
change-id=4 store-id=2 node-id=1 range-id=1 load-delta=[cpu:-80, write-bandwidth:-80, byte-size:-80] start=5m30s gc=10m30s
281282
prev=(replica-id=2 type=VOTER_FULL leaseholder=true)
282283
next=(replica-id=none type=VOTER_FULL)
283284

0 commit comments

Comments
 (0)