github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/store_merge.go (about)

     1  // Copyright 2019 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 kvserver
    12  
    13  import (
    14  	"context"
    15  
    16  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    17  	"github.com/cockroachdb/cockroach/pkg/util/hlc"
    18  	"github.com/cockroachdb/errors"
    19  )
    20  
    21  // MergeRange expands the left-hand replica, leftRepl, to absorb the right-hand
    22  // replica, identified by rightDesc. freezeStart specifies the time at which the
    23  // right-hand replica promised to stop serving traffic and is used to initialize
    24  // the timestamp cache's low water mark for the right-hand keyspace. The
    25  // right-hand replica must exist on this store and the raftMus for both the
    26  // left-hand and right-hand replicas must be held.
    27  func (s *Store) MergeRange(
    28  	ctx context.Context,
    29  	leftRepl *Replica,
    30  	newLeftDesc, rightDesc roachpb.RangeDescriptor,
    31  	freezeStart hlc.Timestamp,
    32  ) error {
    33  	if oldLeftDesc := leftRepl.Desc(); !oldLeftDesc.EndKey.Less(newLeftDesc.EndKey) {
    34  		return errors.Errorf("the new end key is not greater than the current one: %+v <= %+v",
    35  			newLeftDesc.EndKey, oldLeftDesc.EndKey)
    36  	}
    37  
    38  	rightRepl, err := s.GetReplica(rightDesc.RangeID)
    39  	if err != nil {
    40  		return err
    41  	}
    42  
    43  	leftRepl.raftMu.AssertHeld()
    44  	rightRepl.raftMu.AssertHeld()
    45  
    46  	if err := rightRepl.postDestroyRaftMuLocked(ctx, rightRepl.GetMVCCStats()); err != nil {
    47  		return err
    48  	}
    49  
    50  	// Note that we were called (indirectly) from raft processing so we must
    51  	// call removeInitializedReplicaRaftMuLocked directly to avoid deadlocking
    52  	// on the right-hand replica's raftMu.
    53  	if err := s.removeInitializedReplicaRaftMuLocked(ctx, rightRepl, rightDesc.NextReplicaID, RemoveOptions{
    54  		DestroyData: false, // the replica was destroyed when the merge commit applied
    55  	}); err != nil {
    56  		return errors.Errorf("cannot remove range: %s", err)
    57  	}
    58  
    59  	if leftRepl.leaseholderStats != nil {
    60  		leftRepl.leaseholderStats.resetRequestCounts()
    61  	}
    62  	if leftRepl.writeStats != nil {
    63  		// Note: this could be drastically improved by adding a replicaStats method
    64  		// that merges stats. Resetting stats is typically bad for the rebalancing
    65  		// logic that depends on them.
    66  		leftRepl.writeStats.resetRequestCounts()
    67  	}
    68  
    69  	// Clear the concurrency manager's lock and txn wait-queues to redirect the
    70  	// queued transactions to the left-hand replica, if necessary.
    71  	rightRepl.concMgr.OnRangeMerge()
    72  
    73  	leftLease, _ := leftRepl.GetLease()
    74  	rightLease, _ := rightRepl.GetLease()
    75  	if leftLease.OwnedBy(s.Ident.StoreID) && !rightLease.OwnedBy(s.Ident.StoreID) {
    76  		// We hold the lease for the LHS, but do not hold the lease for the RHS.
    77  		// That means we don't have up-to-date timestamp cache entries for the
    78  		// keyspace previously owned by the RHS. Bump the low water mark for the RHS
    79  		// keyspace to freezeStart, the time at which the RHS promised to stop
    80  		// serving traffic, as freezeStart is guaranteed to be greater than any
    81  		// entry in the RHS's timestamp cache.
    82  		//
    83  		// Note that we need to update our clock with freezeStart to preserve the
    84  		// invariant that our clock is always greater than or equal to any
    85  		// timestamps in the timestamp cache. For a full discussion, see the comment
    86  		// on TestStoreRangeMergeTimestampCacheCausality.
    87  		s.Clock().Update(freezeStart)
    88  		setTimestampCacheLowWaterMark(s.tsCache, &rightDesc, freezeStart)
    89  	}
    90  
    91  	// Update the subsuming range's descriptor.
    92  	leftRepl.setDescRaftMuLocked(ctx, &newLeftDesc)
    93  	return nil
    94  }