github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/batcheval/declare.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/spanset"
    18  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    19  	"github.com/cockroachdb/cockroach/pkg/storage/enginepb"
    20  )
    21  
    22  // DefaultDeclareKeys is the default implementation of Command.DeclareKeys.
    23  func DefaultDeclareKeys(
    24  	_ *roachpb.RangeDescriptor,
    25  	header roachpb.Header,
    26  	req roachpb.Request,
    27  	latchSpans, _ *spanset.SpanSet,
    28  ) {
    29  	access := spanset.SpanReadWrite
    30  	if roachpb.IsReadOnly(req) && !roachpb.IsLocking(req) {
    31  		access = spanset.SpanReadOnly
    32  	}
    33  	latchSpans.AddMVCC(access, req.Header().Span(), header.Timestamp)
    34  }
    35  
    36  // DefaultDeclareIsolatedKeys is similar to DefaultDeclareKeys, but it declares
    37  // both lock spans in addition to latch spans. When used, commands will wait on
    38  // locks and wait-queues owned by other transactions before evaluating. This
    39  // ensures that the commands are fully isolated from conflicting transactions
    40  // when it evaluated.
    41  func DefaultDeclareIsolatedKeys(
    42  	_ *roachpb.RangeDescriptor,
    43  	header roachpb.Header,
    44  	req roachpb.Request,
    45  	latchSpans, lockSpans *spanset.SpanSet,
    46  ) {
    47  	access := spanset.SpanReadWrite
    48  	timestamp := header.Timestamp
    49  	if roachpb.IsReadOnly(req) && !roachpb.IsLocking(req) {
    50  		access = spanset.SpanReadOnly
    51  		if header.Txn != nil {
    52  			// For transactional reads, acquire read latches all the way up to
    53  			// the transaction's MaxTimestamp, because reads may observe locks
    54  			// all the way up to this timestamp.
    55  			//
    56  			// TODO(nvanbenschoten): this parallels similar logic in
    57  			// concurrency.Request.readConflictTimestamp, which indicates that
    58  			// there is almost certainly a better way to structure this. There
    59  			// are actually two issues here that lead to this duplication:
    60  			//
    61  			// 1. latch spans and lock spans are declared separately. While these
    62  			//    concepts are not identical, it appears that lock spans are always
    63  			//    a subset of latch spans, which means that we can probably unify
    64  			//    the concepts more closely than we have thus far. This would
    65  			//    probably also have positive performance implications, as the
    66  			//    duplication mandates extra memory allocations.
    67  			//
    68  			// 2. latch spans can each be assigned unique MVCC timestamps but lock
    69  			//    spans inherit the timestamp of their request's transaction (see
    70  			//    lockTable and concurrency.Request.{read,write}ConflictTimestamp).
    71  			//    This difference is strange and confusing. It's not clear that the
    72  			//    generality of latches each being declared at their own timestamp
    73  			//    is useful. There may be an emergent pattern that arises here when
    74  			//    we unify latch and lock spans (see part 1) where latches that are
    75  			//    in the lock span subset can inherit their request's transaction's
    76  			//    timestamp and latches that are not are non-MVCC latches.
    77  			//
    78  			// Note that addressing these issues does not necessarily need to
    79  			// lead to the timestamp that MVCC spans are interpretted at being
    80  			// the same for the purposes of the latch manager and lock-table.
    81  			// For instance, once the lock-table is segregated and all logic
    82  			// relating to "lock discovery" is removed, we no longer need to
    83  			// acquire read latches up to a txn's max timestamp, just to its
    84  			// read timestamp. However, we will still need to search the
    85  			// lock-table up to a txn's max timestamp.
    86  			timestamp.Forward(header.Txn.MaxTimestamp)
    87  		}
    88  	}
    89  	latchSpans.AddMVCC(access, req.Header().Span(), timestamp)
    90  	lockSpans.AddNonMVCC(access, req.Header().Span())
    91  }
    92  
    93  // DeclareKeysForBatch adds all keys that the batch with the provided header
    94  // touches to the given SpanSet. This does not include keys touched during the
    95  // processing of the batch's individual commands.
    96  func DeclareKeysForBatch(
    97  	desc *roachpb.RangeDescriptor, header roachpb.Header, latchSpans *spanset.SpanSet,
    98  ) {
    99  	if header.Txn != nil {
   100  		header.Txn.AssertInitialized(context.TODO())
   101  		latchSpans.AddNonMVCC(spanset.SpanReadOnly, roachpb.Span{
   102  			Key: keys.AbortSpanKey(header.RangeID, header.Txn.ID),
   103  		})
   104  	}
   105  	if header.ReturnRangeInfo {
   106  		latchSpans.AddNonMVCC(spanset.SpanReadOnly, roachpb.Span{Key: keys.RangeLeaseKey(header.RangeID)})
   107  		latchSpans.AddNonMVCC(spanset.SpanReadOnly, roachpb.Span{Key: keys.RangeDescriptorKey(desc.StartKey)})
   108  	}
   109  }
   110  
   111  // CommandArgs contains all the arguments to a command.
   112  // TODO(bdarnell): consider merging with kvserverbase.FilterArgs (which
   113  // would probably require removing the EvalCtx field due to import order
   114  // constraints).
   115  type CommandArgs struct {
   116  	EvalCtx EvalContext
   117  	Header  roachpb.Header
   118  	Args    roachpb.Request
   119  	// *Stats should be mutated to reflect any writes made by the command.
   120  	Stats *enginepb.MVCCStats
   121  }