Skip to content

Commit

Permalink
Merge #48127 #48150
Browse files Browse the repository at this point in the history
48127: builtins: fix ST_Geo[gm]FromGeoJSON(null:::jsonb) r=sumeerbhola a=otan

Fix a bug where annotating jsonb to a null and using it in the
*FromGeoJSON functions will break. This is because `AsText` can return a
nil value.

Release note: None

48150: cli/zip: makes it possible to include/exclude specific nodes r=tbg a=knz

Fixes #42953 

Release note (cli change): `cockroach debug zip` now supports two
command-line parameters `--nodes` and `--exclude-nodes`. When
specified, they control which nodes are inspected when gathering the
data. This makes it possible to focus on a group of nodes of interest
in a large cluster, or to exclude nodes that `debug zip` would have
trouble reaching otherwise. Both flags accept a list of individual
node IDs or ranges of node IDs, e.g. `--nodes=1,10,13-15`.

Co-authored-by: Oliver Tan <otan@cockroachlabs.com>
Co-authored-by: Raphael 'kena' Poss <knz@thaumogen.net>
  • Loading branch information
3 people committed Apr 29, 2020
3 parents 26b9716 + 78ddfaa + bde12bb commit aa7ff4e
Show file tree
Hide file tree
Showing 8 changed files with 374 additions and 1 deletion.
16 changes: 16 additions & 0 deletions pkg/cli/cliflags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1144,4 +1144,20 @@ Addresses for network benchmark.`,
Description: `
Latency or throughput mode.`,
}

ZipNodes = FlagInfo{
Name: "nodes",
Description: `
List of nodes to include. Can be specified as a comma-delimited
list of node IDs or ranges of node IDs, for example: 5,10-20,23.
The default is to include all nodes.`,
}

ZipExcludeNodes = FlagInfo{
Name: "exclude-nodes",
Description: `
List of nodes to exclude. Can be specified as a comma-delimited
list of node IDs or ranges of node IDs, for example: 5,10-20,23.
The default is to not exclude any node.`,
}
)
8 changes: 8 additions & 0 deletions pkg/cli/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ func initCLIDefaults() {
sqlCtx.debugMode = false
sqlCtx.echo = false

zipCtx.nodes = nodeSelection{}

dumpCtx.dumpMode = dumpBoth
dumpCtx.asOf = ""
dumpCtx.dumpAll = false
Expand Down Expand Up @@ -266,6 +268,12 @@ var sqlCtx = struct {
debugMode bool
}{cliContext: &cliCtx}

// zipCtx captures the command-line parameters of the `zip` command.
// Defaults set by InitCLIDefaults() above.
var zipCtx struct {
nodes nodeSelection
}

// dumpCtx captures the command-line parameters of the `dump` command.
// Defaults set by InitCLIDefaults() above.
var dumpCtx struct {
Expand Down
7 changes: 7 additions & 0 deletions pkg/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,13 @@ func init() {
}
}

// Zip command.
{
f := debugZipCmd.Flags()
VarFlag(f, &zipCtx.nodes.inclusive, cliflags.ZipNodes)
VarFlag(f, &zipCtx.nodes.exclusive, cliflags.ZipExcludeNodes)
}

// Decommission command.
VarFlag(decommissionNodeCmd.Flags(), &nodeCtx.nodeDecommissionWait, cliflags.Wait)

Expand Down
183 changes: 183 additions & 0 deletions pkg/cli/testdata/zip/partial1_excluded
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
zip
----
debug zip /dev/null --exclude-nodes=2
establishing RPC connection to ...
retrieving the node status to get the SQL address...
using SQL address: ...
using SQL connection URL: postgresql://...
writing /dev/null
requesting data for debug/events... writing: debug/events.json
requesting data for debug/rangelog... writing: debug/rangelog.json
requesting data for debug/liveness... writing: debug/liveness.json
requesting data for debug/settings... writing: debug/settings.json
requesting data for debug/reports/problemranges... writing: debug/reports/problemranges.json
retrieving SQL data for crdb_internal.cluster_queries... writing: debug/crdb_internal.cluster_queries.txt
retrieving SQL data for crdb_internal.cluster_sessions... writing: debug/crdb_internal.cluster_sessions.txt
retrieving SQL data for crdb_internal.cluster_settings... writing: debug/crdb_internal.cluster_settings.txt
retrieving SQL data for crdb_internal.cluster_transactions... writing: debug/crdb_internal.cluster_transactions.txt
retrieving SQL data for crdb_internal.jobs... writing: debug/crdb_internal.jobs.txt
retrieving SQL data for system.jobs... writing: debug/system.jobs.txt
retrieving SQL data for system.descriptor... writing: debug/system.descriptor.txt
retrieving SQL data for system.namespace... writing: debug/system.namespace.txt
retrieving SQL data for system.namespace2... writing: debug/system.namespace2.txt
retrieving SQL data for crdb_internal.kv_node_status... writing: debug/crdb_internal.kv_node_status.txt
retrieving SQL data for crdb_internal.kv_store_status... writing: debug/crdb_internal.kv_store_status.txt
retrieving SQL data for crdb_internal.schema_changes... writing: debug/crdb_internal.schema_changes.txt
retrieving SQL data for crdb_internal.partitions... writing: debug/crdb_internal.partitions.txt
retrieving SQL data for crdb_internal.zones... writing: debug/crdb_internal.zones.txt
requesting nodes... writing: debug/nodes.json
requesting liveness... writing: debug/liveness.json
writing: debug/nodes/1/status.json
using SQL connection URL for node 1: postgresql://...
retrieving SQL data for crdb_internal.feature_usage... writing: debug/nodes/1/crdb_internal.feature_usage.txt
retrieving SQL data for crdb_internal.gossip_alerts... writing: debug/nodes/1/crdb_internal.gossip_alerts.txt
retrieving SQL data for crdb_internal.gossip_liveness... writing: debug/nodes/1/crdb_internal.gossip_liveness.txt
retrieving SQL data for crdb_internal.gossip_network... writing: debug/nodes/1/crdb_internal.gossip_network.txt
retrieving SQL data for crdb_internal.gossip_nodes... writing: debug/nodes/1/crdb_internal.gossip_nodes.txt
retrieving SQL data for crdb_internal.leases... writing: debug/nodes/1/crdb_internal.leases.txt
retrieving SQL data for crdb_internal.node_build_info... writing: debug/nodes/1/crdb_internal.node_build_info.txt
retrieving SQL data for crdb_internal.node_metrics... writing: debug/nodes/1/crdb_internal.node_metrics.txt
retrieving SQL data for crdb_internal.node_queries... writing: debug/nodes/1/crdb_internal.node_queries.txt
retrieving SQL data for crdb_internal.node_runtime_info... writing: debug/nodes/1/crdb_internal.node_runtime_info.txt
retrieving SQL data for crdb_internal.node_sessions... writing: debug/nodes/1/crdb_internal.node_sessions.txt
retrieving SQL data for crdb_internal.node_statement_statistics... writing: debug/nodes/1/crdb_internal.node_statement_statistics.txt
retrieving SQL data for crdb_internal.node_transactions... writing: debug/nodes/1/crdb_internal.node_transactions.txt
retrieving SQL data for crdb_internal.node_txn_stats... writing: debug/nodes/1/crdb_internal.node_txn_stats.txt
requesting data for debug/nodes/1/details... writing: debug/nodes/1/details.json
requesting data for debug/nodes/1/gossip... writing: debug/nodes/1/gossip.json
requesting data for debug/nodes/1/enginestats... writing: debug/nodes/1/enginestats.json
requesting stacks for node 1... writing: debug/nodes/1/stacks.txt
requesting threads for node 1... writing: debug/nodes/1/threads.txt
requesting heap profile for node 1... writing: debug/nodes/1/heap.pprof
requesting heap files for node 1... writing: debug/nodes/1/heapprof.err.txt
^- resulted in ...
requesting goroutine files for node 1... writing: debug/nodes/1/goroutines.err.txt
^- resulted in ...
requesting log file ...
requesting ranges... 32 found
writing: debug/nodes/1/ranges/1.json
writing: debug/nodes/1/ranges/2.json
writing: debug/nodes/1/ranges/3.json
writing: debug/nodes/1/ranges/4.json
writing: debug/nodes/1/ranges/5.json
writing: debug/nodes/1/ranges/6.json
writing: debug/nodes/1/ranges/7.json
writing: debug/nodes/1/ranges/8.json
writing: debug/nodes/1/ranges/9.json
writing: debug/nodes/1/ranges/10.json
writing: debug/nodes/1/ranges/11.json
writing: debug/nodes/1/ranges/12.json
writing: debug/nodes/1/ranges/13.json
writing: debug/nodes/1/ranges/14.json
writing: debug/nodes/1/ranges/15.json
writing: debug/nodes/1/ranges/16.json
writing: debug/nodes/1/ranges/17.json
writing: debug/nodes/1/ranges/18.json
writing: debug/nodes/1/ranges/19.json
writing: debug/nodes/1/ranges/20.json
writing: debug/nodes/1/ranges/21.json
writing: debug/nodes/1/ranges/22.json
writing: debug/nodes/1/ranges/23.json
writing: debug/nodes/1/ranges/24.json
writing: debug/nodes/1/ranges/25.json
writing: debug/nodes/1/ranges/26.json
writing: debug/nodes/1/ranges/27.json
writing: debug/nodes/1/ranges/28.json
writing: debug/nodes/1/ranges/29.json
writing: debug/nodes/1/ranges/30.json
writing: debug/nodes/1/ranges/31.json
writing: debug/nodes/1/ranges/32.json
writing: debug/nodes/2.skipped
writing: debug/nodes/3/status.json
using SQL connection URL for node 3: postgresql://...
retrieving SQL data for crdb_internal.feature_usage... writing: debug/nodes/3/crdb_internal.feature_usage.txt
retrieving SQL data for crdb_internal.gossip_alerts... writing: debug/nodes/3/crdb_internal.gossip_alerts.txt
retrieving SQL data for crdb_internal.gossip_liveness... writing: debug/nodes/3/crdb_internal.gossip_liveness.txt
retrieving SQL data for crdb_internal.gossip_network... writing: debug/nodes/3/crdb_internal.gossip_network.txt
retrieving SQL data for crdb_internal.gossip_nodes... writing: debug/nodes/3/crdb_internal.gossip_nodes.txt
retrieving SQL data for crdb_internal.leases... writing: debug/nodes/3/crdb_internal.leases.txt
retrieving SQL data for crdb_internal.node_build_info... writing: debug/nodes/3/crdb_internal.node_build_info.txt
retrieving SQL data for crdb_internal.node_metrics... writing: debug/nodes/3/crdb_internal.node_metrics.txt
retrieving SQL data for crdb_internal.node_queries... writing: debug/nodes/3/crdb_internal.node_queries.txt
retrieving SQL data for crdb_internal.node_runtime_info... writing: debug/nodes/3/crdb_internal.node_runtime_info.txt
retrieving SQL data for crdb_internal.node_sessions... writing: debug/nodes/3/crdb_internal.node_sessions.txt
retrieving SQL data for crdb_internal.node_statement_statistics... writing: debug/nodes/3/crdb_internal.node_statement_statistics.txt
retrieving SQL data for crdb_internal.node_transactions... writing: debug/nodes/3/crdb_internal.node_transactions.txt
retrieving SQL data for crdb_internal.node_txn_stats... writing: debug/nodes/3/crdb_internal.node_txn_stats.txt
requesting data for debug/nodes/3/details... writing: debug/nodes/3/details.json
requesting data for debug/nodes/3/gossip... writing: debug/nodes/3/gossip.json
requesting data for debug/nodes/3/enginestats... writing: debug/nodes/3/enginestats.json
requesting stacks for node 3... writing: debug/nodes/3/stacks.txt
requesting threads for node 3... writing: debug/nodes/3/threads.txt
requesting heap profile for node 3... writing: debug/nodes/3/heap.pprof
requesting heap files for node 3... writing: debug/nodes/3/heapprof.err.txt
^- resulted in ...
requesting goroutine files for node 3... writing: debug/nodes/3/goroutines.err.txt
^- resulted in ...
requesting log file ...
requesting ranges... 32 found
writing: debug/nodes/3/ranges/1.json
writing: debug/nodes/3/ranges/2.json
writing: debug/nodes/3/ranges/3.json
writing: debug/nodes/3/ranges/4.json
writing: debug/nodes/3/ranges/5.json
writing: debug/nodes/3/ranges/6.json
writing: debug/nodes/3/ranges/7.json
writing: debug/nodes/3/ranges/8.json
writing: debug/nodes/3/ranges/9.json
writing: debug/nodes/3/ranges/10.json
writing: debug/nodes/3/ranges/11.json
writing: debug/nodes/3/ranges/12.json
writing: debug/nodes/3/ranges/13.json
writing: debug/nodes/3/ranges/14.json
writing: debug/nodes/3/ranges/15.json
writing: debug/nodes/3/ranges/16.json
writing: debug/nodes/3/ranges/17.json
writing: debug/nodes/3/ranges/18.json
writing: debug/nodes/3/ranges/19.json
writing: debug/nodes/3/ranges/20.json
writing: debug/nodes/3/ranges/21.json
writing: debug/nodes/3/ranges/22.json
writing: debug/nodes/3/ranges/23.json
writing: debug/nodes/3/ranges/24.json
writing: debug/nodes/3/ranges/25.json
writing: debug/nodes/3/ranges/26.json
writing: debug/nodes/3/ranges/27.json
writing: debug/nodes/3/ranges/28.json
writing: debug/nodes/3/ranges/29.json
writing: debug/nodes/3/ranges/30.json
writing: debug/nodes/3/ranges/31.json
writing: debug/nodes/3/ranges/32.json
requesting list of SQL databases... 3 found
requesting database details for defaultdb... writing: debug/schema/defaultdb@details.json
0 tables found
requesting database details for postgres... writing: debug/schema/postgres@details.json
0 tables found
requesting database details for system... writing: debug/schema/system@details.json
26 tables found
requesting table details for system.comments... writing: debug/schema/system/comments.json
requesting table details for system.descriptor... writing: debug/schema/system/descriptor.json
requesting table details for system.eventlog... writing: debug/schema/system/eventlog.json
requesting table details for system.jobs... writing: debug/schema/system/jobs.json
requesting table details for system.lease... writing: debug/schema/system/lease.json
requesting table details for system.locations... writing: debug/schema/system/locations.json
requesting table details for system.namespace... writing: debug/schema/system/namespace.json
requesting table details for system.namespace2... writing: debug/schema/system/namespace2.json
requesting table details for system.protected_ts_meta... writing: debug/schema/system/protected_ts_meta.json
requesting table details for system.protected_ts_records... writing: debug/schema/system/protected_ts_records.json
requesting table details for system.rangelog... writing: debug/schema/system/rangelog.json
requesting table details for system.replication_constraint_stats... writing: debug/schema/system/replication_constraint_stats.json
requesting table details for system.replication_critical_localities... writing: debug/schema/system/replication_critical_localities.json
requesting table details for system.replication_stats... writing: debug/schema/system/replication_stats.json
requesting table details for system.reports_meta... writing: debug/schema/system/reports_meta.json
requesting table details for system.role_members... writing: debug/schema/system/role_members.json
requesting table details for system.role_options... writing: debug/schema/system/role_options.json
requesting table details for system.settings... writing: debug/schema/system/settings.json
requesting table details for system.statement_bundle_chunks... writing: debug/schema/system/statement_bundle_chunks.json
requesting table details for system.statement_diagnostics... writing: debug/schema/system/statement_diagnostics.json
requesting table details for system.statement_diagnostics_requests... writing: debug/schema/system/statement_diagnostics_requests.json
requesting table details for system.table_statistics... writing: debug/schema/system/table_statistics.json
requesting table details for system.ui... writing: debug/schema/system/ui.json
requesting table details for system.users... writing: debug/schema/system/users.json
requesting table details for system.web_sessions... writing: debug/schema/system/web_sessions.json
requesting table details for system.zones... writing: debug/schema/system/zones.json
95 changes: 95 additions & 0 deletions pkg/cli/zip.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"time"
"unicode"
Expand Down Expand Up @@ -379,6 +380,7 @@ func runDebugZip(cmd *cobra.Command, args []string) (retErr error) {

for _, node := range nodeList {
nodeID := node.Desc.NodeID

liveness := livenessByNodeID[nodeID]
if liveness == storagepb.NodeLivenessStatus_DECOMMISSIONED {
// Decommissioned + process terminated. Let's not waste time
Expand All @@ -396,6 +398,15 @@ func runDebugZip(cmd *cobra.Command, args []string) (retErr error) {

id := fmt.Sprintf("%d", nodeID)
prefix := fmt.Sprintf("%s/%s", nodesPrefix, id)

if !zipCtx.nodes.isIncluded(nodeID) {
if err := z.createRaw(prefix+".skipped",
[]byte(fmt.Sprintf("skipping excluded node %d\n", nodeID))); err != nil {
return err
}
continue
}

// Don't use sqlConn because that's only for is the node `debug
// zip` was pointed at, but here we want to connect to nodes
// individually to grab node- local SQL tables. Try to guess by
Expand Down Expand Up @@ -726,3 +737,87 @@ func dumpTableDataForZip(
}
return nil
}

type nodeSelection struct {
inclusive rangeSelection
exclusive rangeSelection
includedCache map[int]struct{}
excludedCache map[int]struct{}
}

func (n *nodeSelection) isIncluded(nodeID roachpb.NodeID) bool {
// Avoid recomputing the maps on every call.
if n.includedCache == nil {
n.includedCache = n.inclusive.items()
}
if n.excludedCache == nil {
n.excludedCache = n.exclusive.items()
}

// If the included cache is empty, then we're assuming the node is included.
isIncluded := true
if len(n.includedCache) > 0 {
_, isIncluded = n.includedCache[int(nodeID)]
}
// Then filter out excluded IDs.
if _, excluded := n.excludedCache[int(nodeID)]; excluded {
isIncluded = false
}
return isIncluded
}

type rangeSelection struct {
input string
ranges []vrange
}

type vrange struct {
a, b int
}

func (r *rangeSelection) String() string { return r.input }

func (r *rangeSelection) Type() string {
return "a-b,c,d-e,..."
}

func (r *rangeSelection) Set(v string) error {
r.input = v
for _, rs := range strings.Split(v, ",") {
var thisRange vrange
if strings.Contains(rs, "-") {
ab := strings.SplitN(rs, "-", 2)
a, err := strconv.Atoi(ab[0])
if err != nil {
return err
}
b, err := strconv.Atoi(ab[1])
if err != nil {
return err
}
if b < a {
return errors.New("invalid range")
}
thisRange = vrange{a, b}
} else {
a, err := strconv.Atoi(rs)
if err != nil {
return err
}
thisRange = vrange{a, a}
}
r.ranges = append(r.ranges, thisRange)
}
return nil
}

// items returns the values selected by the range selection
func (r *rangeSelection) items() map[int]struct{} {
s := map[int]struct{}{}
for _, vr := range r.ranges {
for i := vr.a; i <= vr.b; i++ {
s[i] = struct{}{}
}
}
return s
}
Loading

0 comments on commit aa7ff4e

Please sign in to comment.