github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/batcheval/cmd_lease_transfer.go (about) 1 // Copyright 2014 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package batcheval 12 13 import ( 14 "context" 15 16 "github.com/cockroachdb/cockroach/pkg/keys" 17 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/batcheval/result" 18 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset" 19 "github.com/cockroachdb/cockroach/pkg/roachpb" 20 "github.com/cockroachdb/cockroach/pkg/storage" 21 "github.com/cockroachdb/cockroach/pkg/util/log" 22 ) 23 24 func declareKeysTransferLease( 25 desc *roachpb.RangeDescriptor, 26 header roachpb.Header, 27 req roachpb.Request, 28 latchSpans, _ *spanset.SpanSet, 29 ) { 30 latchSpans.AddNonMVCC(spanset.SpanReadWrite, roachpb.Span{Key: keys.RangeLeaseKey(header.RangeID)}) 31 latchSpans.AddNonMVCC(spanset.SpanReadOnly, roachpb.Span{Key: keys.RangeDescriptorKey(desc.StartKey)}) 32 // Cover the entire addressable key space with a latch to prevent any writes 33 // from overlapping with lease transfers. In principle we could just use the 34 // current range descriptor (desc) but it could potentially change due to an 35 // as of yet unapplied merge. 36 latchSpans.AddNonMVCC(spanset.SpanReadOnly, roachpb.Span{Key: keys.LocalMax, EndKey: keys.MaxKey}) 37 } 38 39 func init() { 40 RegisterReadWriteCommand(roachpb.TransferLease, declareKeysTransferLease, TransferLease) 41 } 42 43 // TransferLease sets the lease holder for the range. 44 // Unlike with RequestLease(), the new lease is allowed to overlap the old one, 45 // the contract being that the transfer must have been initiated by the (soon 46 // ex-) lease holder which must have dropped all of its lease holder powers 47 // before proposing. 48 func TransferLease( 49 ctx context.Context, readWriter storage.ReadWriter, cArgs CommandArgs, resp roachpb.Response, 50 ) (result.Result, error) { 51 // When returning an error from this method, must always return 52 // a newFailedLeaseTrigger() to satisfy stats. 53 args := cArgs.Args.(*roachpb.TransferLeaseRequest) 54 55 // For now, don't allow replicas of type LEARNER to be leaseholders. There's 56 // no reason this wouldn't work in principle, but it seems inadvisable. In 57 // particular, learners can't become raft leaders, so we wouldn't be able to 58 // co-locate the leaseholder + raft leader, which is going to affect tail 59 // latencies. Additionally, as of the time of writing, learner replicas are 60 // only used for a short time in replica addition, so it's not worth working 61 // out the edge cases. If we decide to start using long-lived learners at some 62 // point, that math may change. 63 // 64 // If this check is removed at some point, the filtering of learners on the 65 // sending side would have to be removed as well. 66 if err := checkCanReceiveLease(&args.Lease, cArgs.EvalCtx); err != nil { 67 return newFailedLeaseTrigger(true /* isTransfer */), err 68 } 69 70 prevLease, _ := cArgs.EvalCtx.GetLease() 71 log.VEventf(ctx, 2, "lease transfer: prev lease: %+v, new lease: %+v", prevLease, args.Lease) 72 return evalNewLease(ctx, cArgs.EvalCtx, readWriter, cArgs.Stats, 73 args.Lease, prevLease, false /* isExtension */, true /* isTransfer */) 74 }