Skip to content

Commit 92f268a

Browse files
committed
kvserver: ignore lease validity when checking lease preferences
In cockroachdb#107507, we began eagerly enqueuing into the replicate queue, when acquiring a replica acquired a new lease which violated lease preferences. Lease preferences were only considered violated when the lease itself was valid. In cockroachdb#107507, we saw that it is uncommon, but possible for an invalid lease to be acquired, violate lease preferences and not be enqueued as a result. The end result was a leaseholder violating the applied lease preferences which would not be resolved until the next scanner cycle. Update the eager enqueue check to only check that the replica is the incoming leaseholder when applying the lease, and that the replica violates the applied lease preferences. The check now applies on any lease acquisition, where previously it only occurred on the leaseholder changing. Note the purgatory error introduced in cockroachdb#107507, still checks that the lease is valid and owned by the store before proceeding. It is a condition that the lease must be valid+owned by the store to have a change planned, so whilst it is possible the lease becomes invalid somewhere in-between planning, when the replica applies a valid lease, it will still be enqueued, so purgatory is unnecessary. Fixes: cockroachdb#107862 Release note: None
1 parent e9add29 commit 92f268a

File tree

4 files changed

+44
-41
lines changed

4 files changed

+44
-41
lines changed

pkg/kv/kvserver/allocator/plan/replicate.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,8 @@ func (rp ReplicaPlanner) shedLeaseTarget(
963963
liveVoters, _ := rp.storePool.LiveAndDeadReplicas(
964964
existingVoters, false /* includeSuspectAndDrainingStores */)
965965
preferred := rp.allocator.PreferredLeaseholders(rp.storePool, conf, liveVoters)
966-
if len(preferred) > 0 && repl.LeaseViolatesPreferences(ctx) {
966+
if len(preferred) > 0 &&
967+
repl.LeaseViolatesPreferences(ctx) {
967968
return nil, CantTransferLeaseViolatingPreferencesError{RangeID: desc.RangeID}
968969
}
969970
return nil, nil

pkg/kv/kvserver/replica_metrics.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ func calcReplicaMetrics(d calcReplicaMetricsInput) ReplicaMetrics {
149149
validLeaseType = d.leaseStatus.Lease.Type()
150150
if validLeaseOwner {
151151
livenessLease = keys.NodeLivenessSpan.Overlaps(d.desc.RSpan().AsRawSpanWithNoLocals())
152-
switch makeLeasePreferenceStatus(
153-
d.leaseStatus, d.storeID, d.storeAttrs, d.nodeAttrs,
152+
switch checkStoreAgainstLeasePreferences(
153+
d.storeID, d.storeAttrs, d.nodeAttrs,
154154
d.nodeLocality, d.conf.LeasePreferences) {
155155
case leasePreferencesViolating:
156156
violatingLeasePreferences = true

pkg/kv/kvserver/replica_proposal.go

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -517,25 +517,27 @@ func (r *Replica) leasePostApplyLocked(
517517
})
518518
}
519519

520-
// If we acquired a new lease, and it violates the lease preferences, enqueue
521-
// it in the replicate queue.
522-
if leaseChangingHands && iAmTheLeaseHolder {
523-
if LeaseCheckPreferencesOnAcquisitionEnabled.Get(&r.store.cfg.Settings.SV) {
524-
preferenceStatus := makeLeasePreferenceStatus(st, r.store.StoreID(), r.store.Attrs(),
525-
r.store.nodeDesc.Attrs, r.store.nodeDesc.Locality, r.mu.conf.LeasePreferences)
526-
switch preferenceStatus {
527-
case leasePreferencesOK, leasePreferencesLessPreferred, leasePreferencesUnknown:
528-
// We could also enqueue the lease when we are a less preferred
529-
// leaseholder, however the replicate queue will eventually get to it and
530-
// we already satisfy _some_ preference.
531-
case leasePreferencesViolating:
532-
log.VEventf(ctx, 2,
533-
"acquired lease violates lease preferences, enqueueing for transfer [lease=%v preferences=%v]",
534-
newLease, r.mu.conf.LeasePreferences)
535-
r.store.replicateQueue.AddAsync(ctx, r, replicateQueueLeasePreferencePriority)
536-
default:
537-
log.Fatalf(ctx, "unknown lease preferences status: %v", preferenceStatus)
538-
}
520+
// If we acquired a lease, and it violates the lease preferences, enqueue it
521+
// in the replicate queue. NOTE: We don't check whether the lease is valid,
522+
// it is possible that the lease being applied is invalid due to replication
523+
// lag, or previously needing a snapshot. The replicate queue will ensure the
524+
// lease is valid and owned by the replica before processing.
525+
if iAmTheLeaseHolder && leaseChangingHands &&
526+
LeaseCheckPreferencesOnAcquisitionEnabled.Get(&r.store.cfg.Settings.SV) {
527+
preferenceStatus := checkStoreAgainstLeasePreferences(r.store.StoreID(), r.store.Attrs(),
528+
r.store.nodeDesc.Attrs, r.store.nodeDesc.Locality, r.mu.conf.LeasePreferences)
529+
switch preferenceStatus {
530+
case leasePreferencesOK, leasePreferencesLessPreferred:
531+
// We could also enqueue the lease when we are a less preferred
532+
// leaseholder, however the replicate queue will eventually get to it and
533+
// we already satisfy _some_ preference.
534+
case leasePreferencesViolating:
535+
log.VEventf(ctx, 2,
536+
"acquired lease violates lease preferences, enqueuing for transfer [lease=%v preferences=%v]",
537+
newLease, r.mu.conf.LeasePreferences)
538+
r.store.replicateQueue.AddAsync(ctx, r, replicateQueueLeasePreferencePriority)
539+
default:
540+
log.Fatalf(ctx, "unknown lease preferences status: %v", preferenceStatus)
539541
}
540542
}
541543

pkg/kv/kvserver/replica_range_lease.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,16 +1556,14 @@ func (r *Replica) hasCorrectLeaseTypeRLocked(lease roachpb.Lease) bool {
15561556
type leasePreferencesStatus int
15571557

15581558
const (
1559-
// leasePreferencesUnknown indicates the preferences status cannot be
1560-
// determined.
1561-
leasePreferencesUnknown leasePreferencesStatus = iota
1562-
// leasePreferencesViolating indicates the leaseholder does not
1563-
// satisfy any lease preference applied.
1559+
_ leasePreferencesStatus = iota
1560+
// leasePreferencesViolating indicates the checked store does not satisfy any
1561+
// lease preference applied.
15641562
leasePreferencesViolating
1565-
// leasePreferencesLessPreferred indicates the leaseholder satisfies _some_
1563+
// leasePreferencesLessPreferred indicates the checked store satisfies _some_
15661564
// preference, however not the most preferred.
15671565
leasePreferencesLessPreferred
1568-
// leasePreferencesOK indicates the lease satisfies the first
1566+
// leasePreferencesOK indicates the checked store satisfies the first
15691567
// preference, or no lease preferences are applied.
15701568
leasePreferencesOK
15711569
)
@@ -1577,32 +1575,34 @@ func (r *Replica) LeaseViolatesPreferences(ctx context.Context) bool {
15771575
storeID := r.store.StoreID()
15781576
now := r.Clock().NowAsClockTimestamp()
15791577
r.mu.RLock()
1580-
leaseStatus := r.leaseStatusAtRLocked(ctx, now)
15811578
preferences := r.mu.conf.LeasePreferences
1579+
leaseStatus := r.leaseStatusAtRLocked(ctx, now)
15821580
r.mu.RUnlock()
15831581

1582+
if !leaseStatus.IsValid() || !leaseStatus.Lease.OwnedBy(storeID) {
1583+
// We can't determine if the lease preferences are being conformed to or
1584+
// not, as the store either doesn't own the lease, or doesn't own a valid
1585+
// lease.
1586+
return false
1587+
}
1588+
15841589
storeAttrs := r.store.Attrs()
15851590
nodeAttrs := r.store.nodeDesc.Attrs
15861591
nodeLocality := r.store.nodeDesc.Locality
1587-
preferenceStatus := makeLeasePreferenceStatus(
1588-
leaseStatus, storeID, storeAttrs, nodeAttrs, nodeLocality, preferences)
1589-
1592+
preferenceStatus := checkStoreAgainstLeasePreferences(
1593+
storeID, storeAttrs, nodeAttrs, nodeLocality, preferences)
15901594
return preferenceStatus == leasePreferencesViolating
15911595
}
15921596

1593-
func makeLeasePreferenceStatus(
1594-
leaseStatus kvserverpb.LeaseStatus,
1597+
// checkStoreAgainstLeasePreferences returns whether the given store would
1598+
// violate, be less preferred or ok, leaseholder, according the the lease
1599+
// preferences.
1600+
func checkStoreAgainstLeasePreferences(
15951601
storeID roachpb.StoreID,
15961602
storeAttrs, nodeAttrs roachpb.Attributes,
15971603
nodeLocality roachpb.Locality,
15981604
preferences []roachpb.LeasePreference,
15991605
) leasePreferencesStatus {
1600-
if !leaseStatus.IsValid() || !leaseStatus.Lease.OwnedBy(storeID) {
1601-
// We can't determine if the lease preferences are being conformed to or
1602-
// not, as the store either doesn't own the lease, or doesn't own a valid
1603-
// lease.
1604-
return leasePreferencesUnknown
1605-
}
16061606
if len(preferences) == 0 {
16071607
return leasePreferencesOK
16081608
}

0 commit comments

Comments
 (0)