github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/show_trace_replica.go (about)

     1  // Copyright 2018 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 sql
    12  
    13  import (
    14  	"context"
    15  	"regexp"
    16  	"strconv"
    17  	"strings"
    18  
    19  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    20  	"github.com/cockroachdb/errors"
    21  )
    22  
    23  // showTraceReplicaNode is a planNode that wraps another node and uses session
    24  // tracing (via SHOW TRACE) to report the replicas of all kv events that occur
    25  // during its execution. It is used as the top-level node for SHOW
    26  // EXPERIMENTAL_REPLICA TRACE FOR statements.
    27  //
    28  // TODO(dan): This works by selecting trace lines matching certain event
    29  // logs in command execution, which is possibly brittle. A much better
    30  // system would be to set the `ReturnRangeInfo` flag on all kv requests and
    31  // use the `RangeInfo`s that come back. Unfortunately, we wanted to get
    32  // _some_ version of this into 2.0 for partitioning users, but the RangeInfo
    33  // plumbing would have sunk the project. It's also possible that the
    34  // sovereignty work may require the RangeInfo plumbing and we should revisit
    35  // this then.
    36  type showTraceReplicaNode struct {
    37  	optColumnsSlot
    38  
    39  	// plan is the wrapped execution plan that will be traced.
    40  	plan planNode
    41  
    42  	run struct {
    43  		values tree.Datums
    44  	}
    45  }
    46  
    47  func (n *showTraceReplicaNode) startExec(params runParams) error {
    48  	return nil
    49  }
    50  
    51  func (n *showTraceReplicaNode) Next(params runParams) (bool, error) {
    52  	var timestampD tree.Datum
    53  	var tag string
    54  	for {
    55  		ok, err := n.plan.Next(params)
    56  		if !ok || err != nil {
    57  			return ok, err
    58  		}
    59  		values := n.plan.Values()
    60  		// The rows are received from showTraceNode; see ShowTraceColumns.
    61  		const (
    62  			tsCol  = 0
    63  			msgCol = 2
    64  			tagCol = 3
    65  		)
    66  		if replicaMsgRE.MatchString(string(*values[msgCol].(*tree.DString))) {
    67  			timestampD = values[tsCol]
    68  			tag = string(*values[tagCol].(*tree.DString))
    69  			break
    70  		}
    71  	}
    72  
    73  	matches := nodeStoreRangeRE.FindStringSubmatch(tag)
    74  	if matches == nil {
    75  		return false, errors.Errorf(`could not extract node, store, range from: %s`, tag)
    76  	}
    77  	nodeID, err := strconv.Atoi(matches[1])
    78  	if err != nil {
    79  		return false, err
    80  	}
    81  	storeID, err := strconv.Atoi(matches[2])
    82  	if err != nil {
    83  		return false, err
    84  	}
    85  	rangeID, err := strconv.Atoi(matches[3])
    86  	if err != nil {
    87  		return false, err
    88  	}
    89  
    90  	n.run.values = append(
    91  		n.run.values[:0],
    92  		timestampD,
    93  		tree.NewDInt(tree.DInt(nodeID)),
    94  		tree.NewDInt(tree.DInt(storeID)),
    95  		tree.NewDInt(tree.DInt(rangeID)),
    96  	)
    97  	return true, nil
    98  }
    99  
   100  func (n *showTraceReplicaNode) Values() tree.Datums {
   101  	return n.run.values
   102  }
   103  
   104  func (n *showTraceReplicaNode) Close(ctx context.Context) {
   105  	n.plan.Close(ctx)
   106  }
   107  
   108  var nodeStoreRangeRE = regexp.MustCompile(`^\[n(\d+),s(\d+),r(\d+)/`)
   109  
   110  var replicaMsgRE = regexp.MustCompile(
   111  	strings.Join([]string{
   112  		"^read-write path$",
   113  		"^read-only path$",
   114  		"^admin path$",
   115  	}, "|"),
   116  )