github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/batcheval/cmd_resolve_intent.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/hlc"
    22  	"github.com/cockroachdb/cockroach/pkg/util/uuid"
    23  )
    24  
    25  func init() {
    26  	RegisterReadWriteCommand(roachpb.ResolveIntent, declareKeysResolveIntent, ResolveIntent)
    27  }
    28  
    29  func declareKeysResolveIntentCombined(
    30  	header roachpb.Header, req roachpb.Request, latchSpans *spanset.SpanSet,
    31  ) {
    32  	var status roachpb.TransactionStatus
    33  	var txnID uuid.UUID
    34  	var minTxnTS hlc.Timestamp
    35  	switch t := req.(type) {
    36  	case *roachpb.ResolveIntentRequest:
    37  		status = t.Status
    38  		txnID = t.IntentTxn.ID
    39  		minTxnTS = t.IntentTxn.MinTimestamp
    40  	case *roachpb.ResolveIntentRangeRequest:
    41  		status = t.Status
    42  		txnID = t.IntentTxn.ID
    43  		minTxnTS = t.IntentTxn.MinTimestamp
    44  	}
    45  	latchSpans.AddMVCC(spanset.SpanReadWrite, req.Header().Span(), minTxnTS)
    46  	if status == roachpb.ABORTED {
    47  		// We don't always write to the abort span when resolving an ABORTED
    48  		// intent, but we can't tell whether we will or not ahead of time.
    49  		latchSpans.AddNonMVCC(spanset.SpanReadWrite, roachpb.Span{Key: keys.AbortSpanKey(header.RangeID, txnID)})
    50  	}
    51  }
    52  
    53  func declareKeysResolveIntent(
    54  	_ *roachpb.RangeDescriptor,
    55  	header roachpb.Header,
    56  	req roachpb.Request,
    57  	latchSpans, _ *spanset.SpanSet,
    58  ) {
    59  	declareKeysResolveIntentCombined(header, req, latchSpans)
    60  }
    61  
    62  func resolveToMetricType(status roachpb.TransactionStatus, poison bool) *result.Metrics {
    63  	var typ result.Metrics
    64  	if status == roachpb.ABORTED {
    65  		if poison {
    66  			typ.ResolvePoison = 1
    67  		} else {
    68  			typ.ResolveAbort = 1
    69  		}
    70  	} else {
    71  		typ.ResolveCommit = 1
    72  	}
    73  	return &typ
    74  }
    75  
    76  // ResolveIntent resolves a write intent from the specified key
    77  // according to the status of the transaction which created it.
    78  func ResolveIntent(
    79  	ctx context.Context, readWriter storage.ReadWriter, cArgs CommandArgs, resp roachpb.Response,
    80  ) (result.Result, error) {
    81  	args := cArgs.Args.(*roachpb.ResolveIntentRequest)
    82  	h := cArgs.Header
    83  	ms := cArgs.Stats
    84  
    85  	if h.Txn != nil {
    86  		return result.Result{}, ErrTransactionUnsupported
    87  	}
    88  
    89  	update := args.AsLockUpdate()
    90  	ok, err := storage.MVCCResolveWriteIntent(ctx, readWriter, ms, update)
    91  	if err != nil {
    92  		return result.Result{}, err
    93  	}
    94  
    95  	var res result.Result
    96  	res.Local.ResolvedLocks = []roachpb.LockUpdate{update}
    97  	res.Local.Metrics = resolveToMetricType(args.Status, args.Poison)
    98  
    99  	if WriteAbortSpanOnResolve(args.Status, args.Poison, ok) {
   100  		if err := UpdateAbortSpan(ctx, cArgs.EvalCtx, readWriter, ms, args.IntentTxn, args.Poison); err != nil {
   101  			return result.Result{}, err
   102  		}
   103  	}
   104  	return res, nil
   105  }