From c445a945e25feaac90d67212a3e2256730294a48 Mon Sep 17 00:00:00 2001 From: Peter Mattis Date: Fri, 3 Aug 2018 11:47:45 -0400 Subject: [PATCH] cli: allow `node status` to work on unavailable/broken clusters Expand the `crdb_internal.gossip_liveness` and `crdb_internal.gossip_nodes` tables to include columns needed to satisfy the basic usage of `node status`. Specifically, added `address`, `build`, `started_at`, `updated_at` and `replicas` columns. Changed `node status` to use `gossip_{liveness,nodes}` instead of `kv_node_status`. The latter table requires the range containing the consistent node status descriptors to be available, while `gossip_{liveness,nodes}` only retrieves info from gossip. `node status` and `node status --decommission` will work on unavailable/broken clusters as long as the node they are pointed to is up. `node status {--stats,--ranges,--all}` continue to require a reasonably healthy cluster. Fixes #16489 Release note (cli change): Enhance `node status` to work on unavailable/broken clusters. --- c-deps/libroach/protos/roachpb/metadata.pb.cc | 106 ++++++++-- c-deps/libroach/protos/roachpb/metadata.pb.h | 144 +++++++++++-- pkg/cli/cli_test.go | 7 +- pkg/cli/node.go | 27 +-- pkg/roachpb/metadata.pb.go | 198 ++++++++++++------ pkg/roachpb/metadata.proto | 2 + pkg/server/node.go | 7 +- pkg/server/node_test.go | 2 +- pkg/sql/crdb_internal.go | 65 +++++- .../logictest/testdata/planner_test/explain | 2 +- pkg/sql/opt/exec/execbuilder/testdata/explain | 2 +- 11 files changed, 435 insertions(+), 127 deletions(-) diff --git a/c-deps/libroach/protos/roachpb/metadata.pb.cc b/c-deps/libroach/protos/roachpb/metadata.pb.cc index 6d7e857e8caf..7a4b192d362b 100644 --- a/c-deps/libroach/protos/roachpb/metadata.pb.cc +++ b/c-deps/libroach/protos/roachpb/metadata.pb.cc @@ -2363,6 +2363,8 @@ const int NodeDescriptor::kAddressFieldNumber; const int NodeDescriptor::kAttrsFieldNumber; const int NodeDescriptor::kLocalityFieldNumber; const int NodeDescriptor::kServerVersionFieldNumber; +const int NodeDescriptor::kBuildTagFieldNumber; +const int NodeDescriptor::kStartedAtFieldNumber; #endif // !defined(_MSC_VER) || _MSC_VER >= 1900 NodeDescriptor::NodeDescriptor() @@ -2377,6 +2379,10 @@ NodeDescriptor::NodeDescriptor(const NodeDescriptor& from) _internal_metadata_(NULL), _has_bits_(from._has_bits_) { _internal_metadata_.MergeFrom(from._internal_metadata_); + build_tag_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (from.has_build_tag()) { + build_tag_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.build_tag_); + } if (from.has_address()) { address_ = new ::cockroach::util::UnresolvedAddr(*from.address_); } else { @@ -2397,11 +2403,14 @@ NodeDescriptor::NodeDescriptor(const NodeDescriptor& from) } else { serverversion_ = NULL; } - node_id_ = from.node_id_; + ::memcpy(&started_at_, &from.started_at_, + static_cast(reinterpret_cast(&node_id_) - + reinterpret_cast(&started_at_)) + sizeof(node_id_)); // @@protoc_insertion_point(copy_constructor:cockroach.roachpb.NodeDescriptor) } void NodeDescriptor::SharedCtor() { + build_tag_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); ::memset(&address_, 0, static_cast( reinterpret_cast(&node_id_) - reinterpret_cast(&address_)) + sizeof(node_id_)); @@ -2413,6 +2422,7 @@ NodeDescriptor::~NodeDescriptor() { } void NodeDescriptor::SharedDtor() { + build_tag_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete address_; if (this != internal_default_instance()) delete attrs_; if (this != internal_default_instance()) delete locality_; @@ -2435,25 +2445,32 @@ void NodeDescriptor::Clear() { (void) cached_has_bits; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 15u) { + if (cached_has_bits & 31u) { if (cached_has_bits & 0x00000001u) { + build_tag_.ClearNonDefaultToEmptyNoArena(); + } + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(address_ != NULL); address_->Clear(); } - if (cached_has_bits & 0x00000002u) { + if (cached_has_bits & 0x00000004u) { GOOGLE_DCHECK(attrs_ != NULL); attrs_->Clear(); } - if (cached_has_bits & 0x00000004u) { + if (cached_has_bits & 0x00000008u) { GOOGLE_DCHECK(locality_ != NULL); locality_->Clear(); } - if (cached_has_bits & 0x00000008u) { + if (cached_has_bits & 0x00000010u) { GOOGLE_DCHECK(serverversion_ != NULL); serverversion_->Clear(); } } - node_id_ = 0; + if (cached_has_bits & 96u) { + ::memset(&started_at_, 0, static_cast( + reinterpret_cast(&node_id_) - + reinterpret_cast(&started_at_)) + sizeof(node_id_)); + } _has_bits_.Clear(); _internal_metadata_.Clear(); } @@ -2531,6 +2548,30 @@ bool NodeDescriptor::MergePartialFromCodedStream( break; } + case 6: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_build_tag())); + } else { + goto handle_unusual; + } + break; + } + + case 7: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) { + set_has_started_at(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &started_at_))); + } else { + goto handle_unusual; + } + break; + } + default: { handle_unusual: if (tag == 0) { @@ -2558,30 +2599,39 @@ void NodeDescriptor::SerializeWithCachedSizes( (void) cached_has_bits; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000010u) { + if (cached_has_bits & 0x00000040u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->node_id(), output); } - if (cached_has_bits & 0x00000001u) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 2, this->_internal_address(), output); } - if (cached_has_bits & 0x00000002u) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 3, this->_internal_attrs(), output); } - if (cached_has_bits & 0x00000004u) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 4, this->_internal_locality(), output); } - if (cached_has_bits & 0x00000008u) { + if (cached_has_bits & 0x00000010u) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 5, this->_internal_serverversion(), output); } + if (cached_has_bits & 0x00000001u) { + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 6, this->build_tag(), output); + } + + if (cached_has_bits & 0x00000020u) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(7, this->started_at(), output); + } + output->WriteRaw(_internal_metadata_.unknown_fields().data(), static_cast(_internal_metadata_.unknown_fields().size())); // @@protoc_insertion_point(serialize_end:cockroach.roachpb.NodeDescriptor) @@ -2593,7 +2643,13 @@ size_t NodeDescriptor::ByteSizeLong() const { total_size += _internal_metadata_.unknown_fields().size(); - if (_has_bits_[0 / 32] & 31u) { + if (_has_bits_[0 / 32] & 127u) { + if (has_build_tag()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->build_tag()); + } + if (has_address()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSize( @@ -2618,6 +2674,12 @@ size_t NodeDescriptor::ByteSizeLong() const { *serverversion_); } + if (has_started_at()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->started_at()); + } + if (has_node_id()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::Int32Size( @@ -2643,20 +2705,27 @@ void NodeDescriptor::MergeFrom(const NodeDescriptor& from) { (void) cached_has_bits; cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 31u) { + if (cached_has_bits & 127u) { if (cached_has_bits & 0x00000001u) { - mutable_address()->::cockroach::util::UnresolvedAddr::MergeFrom(from.address()); + set_has_build_tag(); + build_tag_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.build_tag_); } if (cached_has_bits & 0x00000002u) { - mutable_attrs()->::cockroach::roachpb::Attributes::MergeFrom(from.attrs()); + mutable_address()->::cockroach::util::UnresolvedAddr::MergeFrom(from.address()); } if (cached_has_bits & 0x00000004u) { - mutable_locality()->::cockroach::roachpb::Locality::MergeFrom(from.locality()); + mutable_attrs()->::cockroach::roachpb::Attributes::MergeFrom(from.attrs()); } if (cached_has_bits & 0x00000008u) { - mutable_serverversion()->::cockroach::roachpb::Version::MergeFrom(from.serverversion()); + mutable_locality()->::cockroach::roachpb::Locality::MergeFrom(from.locality()); } if (cached_has_bits & 0x00000010u) { + mutable_serverversion()->::cockroach::roachpb::Version::MergeFrom(from.serverversion()); + } + if (cached_has_bits & 0x00000020u) { + started_at_ = from.started_at_; + } + if (cached_has_bits & 0x00000040u) { node_id_ = from.node_id_; } _has_bits_[0] |= cached_has_bits; @@ -2680,10 +2749,13 @@ void NodeDescriptor::Swap(NodeDescriptor* other) { } void NodeDescriptor::InternalSwap(NodeDescriptor* other) { using std::swap; + build_tag_.Swap(&other->build_tag_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); swap(address_, other->address_); swap(attrs_, other->attrs_); swap(locality_, other->locality_); swap(serverversion_, other->serverversion_); + swap(started_at_, other->started_at_); swap(node_id_, other->node_id_); swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); diff --git a/c-deps/libroach/protos/roachpb/metadata.pb.h b/c-deps/libroach/protos/roachpb/metadata.pb.h index 500c955a617b..be624467e3d8 100644 --- a/c-deps/libroach/protos/roachpb/metadata.pb.h +++ b/c-deps/libroach/protos/roachpb/metadata.pb.h @@ -1223,6 +1223,20 @@ class NodeDescriptor : public ::google::protobuf::MessageLite /* @@protoc_insert // accessors ------------------------------------------------------- + bool has_build_tag() const; + void clear_build_tag(); + static const int kBuildTagFieldNumber = 6; + const ::std::string& build_tag() const; + void set_build_tag(const ::std::string& value); + #if LANG_CXX11 + void set_build_tag(::std::string&& value); + #endif + void set_build_tag(const char* value); + void set_build_tag(const char* value, size_t size); + ::std::string* mutable_build_tag(); + ::std::string* release_build_tag(); + void set_allocated_build_tag(::std::string* build_tag); + bool has_address() const; void clear_address(); static const int kAddressFieldNumber = 2; @@ -1267,6 +1281,12 @@ class NodeDescriptor : public ::google::protobuf::MessageLite /* @@protoc_insert ::cockroach::roachpb::Version* mutable_serverversion(); void set_allocated_serverversion(::cockroach::roachpb::Version* serverversion); + bool has_started_at() const; + void clear_started_at(); + static const int kStartedAtFieldNumber = 7; + ::google::protobuf::int64 started_at() const; + void set_started_at(::google::protobuf::int64 value); + bool has_node_id() const; void clear_node_id(); static const int kNodeIdFieldNumber = 1; @@ -1285,14 +1305,20 @@ class NodeDescriptor : public ::google::protobuf::MessageLite /* @@protoc_insert void clear_has_locality(); void set_has_serverversion(); void clear_has_serverversion(); + void set_has_build_tag(); + void clear_has_build_tag(); + void set_has_started_at(); + void clear_has_started_at(); ::google::protobuf::internal::InternalMetadataWithArenaLite _internal_metadata_; ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; + ::google::protobuf::internal::ArenaStringPtr build_tag_; ::cockroach::util::UnresolvedAddr* address_; ::cockroach::roachpb::Attributes* attrs_; ::cockroach::roachpb::Locality* locality_; ::cockroach::roachpb::Version* serverversion_; + ::google::protobuf::int64 started_at_; ::google::protobuf::int32 node_id_; friend struct ::protobuf_roachpb_2fmetadata_2eproto::TableStruct; }; @@ -2904,13 +2930,13 @@ inline void StoreCapacity::set_allocated_writes_per_replica(::cockroach::roachpb // NodeDescriptor inline bool NodeDescriptor::has_node_id() const { - return (_has_bits_[0] & 0x00000010u) != 0; + return (_has_bits_[0] & 0x00000040u) != 0; } inline void NodeDescriptor::set_has_node_id() { - _has_bits_[0] |= 0x00000010u; + _has_bits_[0] |= 0x00000040u; } inline void NodeDescriptor::clear_has_node_id() { - _has_bits_[0] &= ~0x00000010u; + _has_bits_[0] &= ~0x00000040u; } inline void NodeDescriptor::clear_node_id() { node_id_ = 0; @@ -2927,13 +2953,13 @@ inline void NodeDescriptor::set_node_id(::google::protobuf::int32 value) { } inline bool NodeDescriptor::has_address() const { - return (_has_bits_[0] & 0x00000001u) != 0; + return (_has_bits_[0] & 0x00000002u) != 0; } inline void NodeDescriptor::set_has_address() { - _has_bits_[0] |= 0x00000001u; + _has_bits_[0] |= 0x00000002u; } inline void NodeDescriptor::clear_has_address() { - _has_bits_[0] &= ~0x00000001u; + _has_bits_[0] &= ~0x00000002u; } inline const ::cockroach::util::UnresolvedAddr& NodeDescriptor::_internal_address() const { return *address_; @@ -2980,13 +3006,13 @@ inline void NodeDescriptor::set_allocated_address(::cockroach::util::UnresolvedA } inline bool NodeDescriptor::has_attrs() const { - return (_has_bits_[0] & 0x00000002u) != 0; + return (_has_bits_[0] & 0x00000004u) != 0; } inline void NodeDescriptor::set_has_attrs() { - _has_bits_[0] |= 0x00000002u; + _has_bits_[0] |= 0x00000004u; } inline void NodeDescriptor::clear_has_attrs() { - _has_bits_[0] &= ~0x00000002u; + _has_bits_[0] &= ~0x00000004u; } inline void NodeDescriptor::clear_attrs() { if (attrs_ != NULL) attrs_->Clear(); @@ -3037,13 +3063,13 @@ inline void NodeDescriptor::set_allocated_attrs(::cockroach::roachpb::Attributes } inline bool NodeDescriptor::has_locality() const { - return (_has_bits_[0] & 0x00000004u) != 0; + return (_has_bits_[0] & 0x00000008u) != 0; } inline void NodeDescriptor::set_has_locality() { - _has_bits_[0] |= 0x00000004u; + _has_bits_[0] |= 0x00000008u; } inline void NodeDescriptor::clear_has_locality() { - _has_bits_[0] &= ~0x00000004u; + _has_bits_[0] &= ~0x00000008u; } inline void NodeDescriptor::clear_locality() { if (locality_ != NULL) locality_->Clear(); @@ -3094,13 +3120,13 @@ inline void NodeDescriptor::set_allocated_locality(::cockroach::roachpb::Localit } inline bool NodeDescriptor::has_serverversion() const { - return (_has_bits_[0] & 0x00000008u) != 0; + return (_has_bits_[0] & 0x00000010u) != 0; } inline void NodeDescriptor::set_has_serverversion() { - _has_bits_[0] |= 0x00000008u; + _has_bits_[0] |= 0x00000010u; } inline void NodeDescriptor::clear_has_serverversion() { - _has_bits_[0] &= ~0x00000008u; + _has_bits_[0] &= ~0x00000010u; } inline void NodeDescriptor::clear_serverversion() { if (serverversion_ != NULL) serverversion_->Clear(); @@ -3150,6 +3176,94 @@ inline void NodeDescriptor::set_allocated_serverversion(::cockroach::roachpb::Ve // @@protoc_insertion_point(field_set_allocated:cockroach.roachpb.NodeDescriptor.ServerVersion) } +inline bool NodeDescriptor::has_build_tag() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void NodeDescriptor::set_has_build_tag() { + _has_bits_[0] |= 0x00000001u; +} +inline void NodeDescriptor::clear_has_build_tag() { + _has_bits_[0] &= ~0x00000001u; +} +inline void NodeDescriptor::clear_build_tag() { + build_tag_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_build_tag(); +} +inline const ::std::string& NodeDescriptor::build_tag() const { + // @@protoc_insertion_point(field_get:cockroach.roachpb.NodeDescriptor.build_tag) + return build_tag_.GetNoArena(); +} +inline void NodeDescriptor::set_build_tag(const ::std::string& value) { + set_has_build_tag(); + build_tag_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:cockroach.roachpb.NodeDescriptor.build_tag) +} +#if LANG_CXX11 +inline void NodeDescriptor::set_build_tag(::std::string&& value) { + set_has_build_tag(); + build_tag_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:cockroach.roachpb.NodeDescriptor.build_tag) +} +#endif +inline void NodeDescriptor::set_build_tag(const char* value) { + GOOGLE_DCHECK(value != NULL); + set_has_build_tag(); + build_tag_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:cockroach.roachpb.NodeDescriptor.build_tag) +} +inline void NodeDescriptor::set_build_tag(const char* value, size_t size) { + set_has_build_tag(); + build_tag_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:cockroach.roachpb.NodeDescriptor.build_tag) +} +inline ::std::string* NodeDescriptor::mutable_build_tag() { + set_has_build_tag(); + // @@protoc_insertion_point(field_mutable:cockroach.roachpb.NodeDescriptor.build_tag) + return build_tag_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* NodeDescriptor::release_build_tag() { + // @@protoc_insertion_point(field_release:cockroach.roachpb.NodeDescriptor.build_tag) + if (!has_build_tag()) { + return NULL; + } + clear_has_build_tag(); + return build_tag_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void NodeDescriptor::set_allocated_build_tag(::std::string* build_tag) { + if (build_tag != NULL) { + set_has_build_tag(); + } else { + clear_has_build_tag(); + } + build_tag_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), build_tag); + // @@protoc_insertion_point(field_set_allocated:cockroach.roachpb.NodeDescriptor.build_tag) +} + +inline bool NodeDescriptor::has_started_at() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void NodeDescriptor::set_has_started_at() { + _has_bits_[0] |= 0x00000020u; +} +inline void NodeDescriptor::clear_has_started_at() { + _has_bits_[0] &= ~0x00000020u; +} +inline void NodeDescriptor::clear_started_at() { + started_at_ = GOOGLE_LONGLONG(0); + clear_has_started_at(); +} +inline ::google::protobuf::int64 NodeDescriptor::started_at() const { + // @@protoc_insertion_point(field_get:cockroach.roachpb.NodeDescriptor.started_at) + return started_at_; +} +inline void NodeDescriptor::set_started_at(::google::protobuf::int64 value) { + set_has_started_at(); + started_at_ = value; + // @@protoc_insertion_point(field_set:cockroach.roachpb.NodeDescriptor.started_at) +} + // ------------------------------------------------------------------- // StoreDescriptor diff --git a/pkg/cli/cli_test.go b/pkg/cli/cli_test.go index 770374a2cef8..d99ee16dd847 100644 --- a/pkg/cli/cli_test.go +++ b/pkg/cli/cli_test.go @@ -1908,14 +1908,15 @@ func TestCLITimeout(t *testing.T) { // Wrap the meat of the test in a retry loop. Setting a timeout like this is // racy as the operation may have succeeded by the time the scheduler gives - // the timeout a chance to have an effect. + // the timeout a chance to have an effect. We specify --all to include some + // slower to access virtual tables in the query. testutils.SucceedsSoon(t, func() error { - out, err := c.RunWithCapture("node status 1 --timeout 1ns") + out, err := c.RunWithCapture("node status 1 --all --timeout 1ns") if err != nil { t.Fatal(err) } - const exp = `node status 1 --timeout 1ns + const exp = `node status 1 --all --timeout 1ns pq: query execution canceled due to statement timeout ` if out != exp { diff --git a/pkg/cli/node.go b/pkg/cli/node.go index 28ae9d9021d2..4d98ec22db79 100644 --- a/pkg/cli/node.go +++ b/pkg/cli/node.go @@ -111,8 +111,8 @@ var statusNodeCmd = &cobra.Command{ Use: "status []", Short: "shows the status of a node or all nodes", Long: ` - If a node ID is specified, this will show the status for the corresponding node. If no node ID - is specified, this will display the status for all nodes in the cluster. +If a node ID is specified, this will show the status for the corresponding node. If no node ID +is specified, this will display the status for all nodes in the cluster. `, Args: cobra.MaximumNArgs(1), RunE: MaybeDecorateGRPCError(runStatusNode), @@ -150,8 +150,13 @@ func runStatusNodeInner(showDecommissioned bool, args []string) ([]string, [][]s } baseQuery := joinUsingID( - []string{ - "SELECT node_id AS id, address, tag AS build, started_at, updated_at from crdb_internal.kv_node_status", + []string{` +SELECT node_id AS id, + address, + build_tag AS build, + started_at, + updated_at +FROM crdb_internal.gossip_liveness JOIN crdb_internal.gossip_nodes USING (node_id)`, maybeAddActiveNodesFilter( `SELECT node_id AS id, CASE WHEN split_part(expiration,',',1)::decimal > now()::decimal @@ -183,14 +188,12 @@ SELECT node_id AS id, FROM crdb_internal.kv_store_status GROUP BY node_id` - decommissionQuery := joinUsingID( - []string{ - `SELECT node_id AS id, sum((metrics->>'replicas')::DECIMAL)::INT AS gossiped_replicas - FROM crdb_internal.kv_store_status GROUP BY node_id`, - `SELECT node_id AS id, decommissioning AS is_decommissioning, draining AS is_draining - FROM crdb_internal.gossip_liveness`, - }, - ) + decommissionQuery := ` +SELECT node_id AS id, + decommissioning AS is_decommissioning, + draining AS is_draining, + ranges AS gossiped_replicas +FROM crdb_internal.gossip_liveness JOIN crdb_internal.gossip_nodes USING (node_id)` conn, err := getPasswordAndMakeSQLClient("cockroach node status") if err != nil { diff --git a/pkg/roachpb/metadata.pb.go b/pkg/roachpb/metadata.pb.go index 086dd28722e3..070b4bcbe724 100644 --- a/pkg/roachpb/metadata.pb.go +++ b/pkg/roachpb/metadata.pb.go @@ -152,6 +152,8 @@ type NodeDescriptor struct { Attrs Attributes `protobuf:"bytes,3,opt,name=attrs" json:"attrs"` Locality Locality `protobuf:"bytes,4,opt,name=locality" json:"locality"` ServerVersion Version `protobuf:"bytes,5,opt,name=ServerVersion" json:"ServerVersion"` + BuildTag string `protobuf:"bytes,6,opt,name=build_tag,json=buildTag" json:"build_tag"` + StartedAt int64 `protobuf:"varint,7,opt,name=started_at,json=startedAt" json:"started_at"` } func (m *NodeDescriptor) Reset() { *m = NodeDescriptor{} } @@ -651,6 +653,13 @@ func (m *NodeDescriptor) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n7 + dAtA[i] = 0x32 + i++ + i = encodeVarintMetadata(dAtA, i, uint64(len(m.BuildTag))) + i += copy(dAtA[i:], m.BuildTag) + dAtA[i] = 0x38 + i++ + i = encodeVarintMetadata(dAtA, i, uint64(m.StartedAt)) return i, nil } @@ -1057,6 +1066,9 @@ func (m *NodeDescriptor) Size() (n int) { n += 1 + l + sovMetadata(uint64(l)) l = m.ServerVersion.Size() n += 1 + l + sovMetadata(uint64(l)) + l = len(m.BuildTag) + n += 1 + l + sovMetadata(uint64(l)) + n += 1 + sovMetadata(uint64(m.StartedAt)) return n } @@ -2215,6 +2227,54 @@ func (m *NodeDescriptor) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BuildTag", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetadata + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMetadata + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BuildTag = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartedAt", wireType) + } + m.StartedAt = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetadata + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartedAt |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipMetadata(dAtA[iNdEx:]) @@ -2918,72 +2978,74 @@ var ( func init() { proto.RegisterFile("roachpb/metadata.proto", fileDescriptorMetadata) } var fileDescriptorMetadata = []byte{ - // 1072 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x6f, 0x1b, 0xc5, - 0x17, 0xcf, 0xda, 0xeb, 0xec, 0xfa, 0x25, 0xfe, 0xa6, 0x1e, 0x7d, 0x29, 0x2b, 0x23, 0xec, 0x64, - 0x45, 0xa5, 0xf2, 0x43, 0x49, 0x6a, 0x64, 0x55, 0x09, 0x2a, 0x10, 0x37, 0x54, 0x0a, 0xa5, 0x55, - 0xb4, 0x29, 0x3d, 0x70, 0xb1, 0x26, 0xbb, 0x43, 0xba, 0x64, 0xb3, 0x6b, 0x66, 0xc7, 0x6e, 0x7c, - 0x47, 0xe2, 0x80, 0x90, 0x38, 0x72, 0xcc, 0xa5, 0xff, 0x01, 0x07, 0xfe, 0x01, 0xa4, 0x88, 0x13, - 0x47, 0x4e, 0x11, 0x98, 0x0b, 0x67, 0x8e, 0x39, 0xa1, 0x79, 0x3b, 0xb3, 0x5e, 0xbb, 0xae, 0x44, - 0x8a, 0xc4, 0x6d, 0xfc, 0xde, 0xe7, 0xf3, 0xf6, 0xcd, 0xe7, 0xcd, 0x7c, 0xc6, 0x70, 0x9d, 0x27, - 0xd4, 0x7f, 0xd2, 0x3f, 0xdc, 0x38, 0x61, 0x82, 0x06, 0x54, 0xd0, 0xf5, 0x3e, 0x4f, 0x44, 0x42, - 0xea, 0x7e, 0xe2, 0x1f, 0x63, 0x6e, 0x5d, 0x21, 0x1a, 0x8d, 0x81, 0x08, 0xa3, 0x8d, 0x41, 0xcc, - 0x59, 0x9a, 0x44, 0x43, 0x16, 0xf4, 0x68, 0x10, 0xf0, 0x0c, 0xde, 0xf8, 0xff, 0x51, 0x72, 0x94, - 0xe0, 0x72, 0x43, 0xae, 0xb2, 0xa8, 0xfb, 0x01, 0xc0, 0x8e, 0x10, 0x3c, 0x3c, 0x1c, 0x08, 0x96, - 0x92, 0xb7, 0xa1, 0x42, 0x85, 0xe0, 0xa9, 0x63, 0xac, 0x96, 0x6f, 0x56, 0xbb, 0xaf, 0xfc, 0x75, - 0xd1, 0xaa, 0x8f, 0xe8, 0x49, 0xb4, 0xed, 0x62, 0xf8, 0x9d, 0xcf, 0xa3, 0xe4, 0xa9, 0xeb, 0x65, - 0x98, 0x6d, 0xf3, 0xfb, 0xb3, 0xd6, 0x82, 0xfb, 0xb5, 0x01, 0x75, 0x8f, 0xf5, 0xa3, 0xd0, 0xa7, - 0x22, 0x4c, 0xe2, 0x47, 0x94, 0x1f, 0x31, 0x41, 0x6e, 0x81, 0x15, 0x27, 0x01, 0xeb, 0x85, 0x81, - 0x63, 0xac, 0x1a, 0x37, 0x2b, 0x5d, 0xe7, 0xfc, 0xa2, 0xb5, 0x30, 0xbe, 0x68, 0x2d, 0x3e, 0x4c, - 0x02, 0xb6, 0xb7, 0x7b, 0x99, 0xaf, 0xbc, 0x45, 0x09, 0xdc, 0x0b, 0x48, 0x07, 0xec, 0x54, 0x24, - 0x1c, 0x39, 0x25, 0xe4, 0x34, 0x14, 0xc7, 0x3a, 0x90, 0x71, 0x24, 0xe9, 0xa5, 0x67, 0x21, 0x76, - 0x2f, 0xd8, 0xb6, 0x65, 0x17, 0x7f, 0x9e, 0xb5, 0x0c, 0xf7, 0xe7, 0x49, 0x27, 0xbb, 0x2c, 0xf5, - 0x79, 0xd8, 0x17, 0x09, 0xff, 0xef, 0x3a, 0x21, 0x77, 0x00, 0x78, 0xf6, 0x79, 0x49, 0x2c, 0x23, - 0xb1, 0xa9, 0x88, 0x55, 0xd5, 0x18, 0x52, 0x27, 0x3f, 0xbc, 0xaa, 0x62, 0xec, 0x05, 0xdb, 0xcb, - 0x72, 0x23, 0x3f, 0x9e, 0xb5, 0x0c, 0xdc, 0xcc, 0x37, 0x06, 0x2c, 0x6b, 0x58, 0xc0, 0x62, 0x21, - 0x9b, 0xe2, 0x34, 0x3e, 0xca, 0x37, 0x52, 0x9e, 0x34, 0xe5, 0xc9, 0x78, 0xd6, 0x94, 0x5a, 0x7a, - 0x16, 0x62, 0xf7, 0x02, 0xb2, 0x0b, 0x96, 0xfa, 0x04, 0x6e, 0x65, 0xa9, 0xfd, 0xc6, 0xfa, 0x73, - 0xc7, 0x66, 0xfd, 0x39, 0xd5, 0xba, 0xa6, 0xac, 0xed, 0x69, 0xaa, 0xfb, 0x43, 0x09, 0x56, 0xb0, - 0x74, 0x41, 0xd8, 0x97, 0x6c, 0xe8, 0x06, 0x54, 0x53, 0x41, 0xb9, 0xe8, 0x1d, 0xb3, 0x11, 0xb6, - 0xb4, 0xdc, 0xb5, 0x2f, 0x2f, 0x5a, 0xa6, 0x77, 0x9f, 0x8d, 0x3c, 0x1b, 0x53, 0xf7, 0xd9, 0x88, - 0xac, 0x81, 0xc5, 0xe2, 0x00, 0x41, 0xe5, 0x19, 0xd0, 0x22, 0x8b, 0x03, 0x09, 0xb9, 0x07, 0xb6, - 0xea, 0x2f, 0x75, 0xcc, 0xd5, 0xf2, 0x15, 0xf7, 0x96, 0x73, 0xc9, 0xc7, 0xb0, 0x12, 0xb3, 0x53, - 0xd1, 0x2b, 0x0c, 0xaf, 0x82, 0xc3, 0x73, 0xd5, 0x7e, 0x6a, 0x0f, 0xd9, 0xa9, 0x78, 0xc1, 0x00, - 0x6b, 0x71, 0x21, 0x37, 0x3b, 0xc4, 0x67, 0x06, 0x2c, 0xed, 0x33, 0xee, 0xb3, 0x58, 0x84, 0x11, - 0x4b, 0xc9, 0x75, 0x28, 0xf7, 0x6f, 0x6d, 0xa2, 0x5a, 0x86, 0x6a, 0x43, 0x06, 0x30, 0xde, 0xee, - 0xa0, 0x1a, 0x93, 0x78, 0xbb, 0x83, 0xf1, 0xce, 0x26, 0x0a, 0x30, 0x89, 0x77, 0x32, 0xfc, 0xed, - 0x8e, 0x63, 0x4e, 0xc5, 0x6f, 0x67, 0xf8, 0xad, 0x4d, 0xec, 0x7e, 0x12, 0xdf, 0xda, 0x24, 0x0e, - 0x98, 0xfd, 0x07, 0xf4, 0xd4, 0x59, 0x2c, 0x24, 0x30, 0xa2, 0xee, 0xf0, 0x65, 0x19, 0x6a, 0x78, - 0x9c, 0xef, 0xd2, 0x3e, 0xf5, 0x43, 0x31, 0x22, 0xab, 0x60, 0xfb, 0x6a, 0xad, 0x86, 0xab, 0x54, - 0xd3, 0x51, 0xe2, 0x42, 0x95, 0x0e, 0x69, 0x18, 0xd1, 0xc3, 0x88, 0x61, 0xe7, 0x1a, 0x32, 0x09, - 0x93, 0x1b, 0xb0, 0x94, 0x1d, 0x11, 0x3f, 0x19, 0xc4, 0x42, 0x5d, 0x89, 0x0c, 0x05, 0x98, 0xb8, - 0x2b, 0xe3, 0x12, 0x16, 0x31, 0x9a, 0x6a, 0x98, 0x59, 0x84, 0x61, 0x22, 0x83, 0x6d, 0x42, 0xfd, - 0x29, 0x0f, 0x05, 0x4b, 0x7b, 0x7d, 0xc6, 0x7b, 0x29, 0xf3, 0x93, 0x38, 0x98, 0xda, 0xeb, 0x4a, - 0x96, 0xde, 0x67, 0xfc, 0x00, 0x93, 0x64, 0x1f, 0xea, 0x87, 0x23, 0x4d, 0xd0, 0xd7, 0x60, 0x11, - 0xaf, 0x41, 0x73, 0xce, 0x51, 0x29, 0x8c, 0x4a, 0x57, 0x44, 0xfa, 0x3e, 0xe3, 0x6a, 0xc2, 0xc4, - 0x03, 0x52, 0xe8, 0x41, 0x97, 0xb4, 0xae, 0x50, 0xf2, 0x5a, 0xde, 0xa4, 0xae, 0xe9, 0x80, 0x39, - 0x48, 0x59, 0xe0, 0xd8, 0x05, 0x11, 0x31, 0x42, 0xde, 0x84, 0x5a, 0x94, 0x1c, 0x85, 0x3e, 0x8d, - 0x7a, 0xd8, 0x88, 0x53, 0x2d, 0x40, 0x96, 0x55, 0xaa, 0x2b, 0x33, 0xa4, 0x0d, 0xe4, 0xcb, 0x01, - 0xe3, 0xe1, 0xb4, 0x3a, 0x50, 0x50, 0xe7, 0x9a, 0xca, 0xe7, 0xf2, 0xa8, 0xe1, 0xff, 0x54, 0x82, - 0xff, 0x49, 0x03, 0xfc, 0x77, 0x9e, 0xf9, 0x3e, 0x58, 0xf2, 0xad, 0x61, 0x69, 0xaa, 0x7c, 0xa6, - 0xa8, 0x86, 0x7c, 0x95, 0xd6, 0x3f, 0xcd, 0x5f, 0xa5, 0x9d, 0x20, 0xc8, 0x1d, 0x46, 0x91, 0xc8, - 0x96, 0x7e, 0x79, 0xca, 0xc8, 0x7e, 0x7d, 0x8e, 0x96, 0x93, 0x77, 0x4a, 0x91, 0x33, 0x06, 0xb9, - 0x03, 0x76, 0x94, 0xf8, 0x34, 0x92, 0x67, 0xd5, 0x44, 0xf6, 0x6b, 0x73, 0xd8, 0x9f, 0x28, 0x88, - 0x3e, 0xc8, 0x9a, 0x42, 0xee, 0x41, 0xed, 0x80, 0xf1, 0x21, 0xe3, 0x8f, 0x19, 0x4f, 0xc3, 0x24, - 0xc6, 0x23, 0xb5, 0xd4, 0x6e, 0xcc, 0xa9, 0xa1, 0x10, 0xaa, 0xc4, 0x34, 0xcd, 0xfd, 0xaa, 0x04, - 0x2b, 0x78, 0x89, 0xa6, 0x3d, 0x32, 0x7f, 0x49, 0x8c, 0x7f, 0xfe, 0x92, 0xe4, 0x62, 0x94, 0xae, - 0x2c, 0xc6, 0x7b, 0x60, 0xca, 0x89, 0x28, 0x19, 0xd7, 0xe6, 0x30, 0xa7, 0x67, 0xad, 0xcf, 0x9b, - 0x24, 0x91, 0x6e, 0xe1, 0xd6, 0x67, 0x4a, 0xae, 0xce, 0x29, 0x30, 0xe5, 0x14, 0xb3, 0xbe, 0xe0, - 0x7e, 0x6b, 0x40, 0x5d, 0xc9, 0x40, 0x03, 0x4f, 0x7b, 0xec, 0x4b, 0x0a, 0xb1, 0x53, 0xb0, 0xf8, - 0x12, 0x5a, 0x7c, 0xeb, 0xc5, 0x16, 0x8f, 0xef, 0xe4, 0xac, 0xbb, 0xbb, 0x1f, 0x81, 0xad, 0x47, - 0x4f, 0xde, 0x85, 0x8a, 0x08, 0x99, 0xfa, 0x7b, 0xb3, 0xd4, 0x7e, 0x75, 0x4e, 0xad, 0x47, 0x21, - 0xd3, 0x9a, 0x64, 0x58, 0x75, 0x4b, 0x3e, 0x04, 0x53, 0xa6, 0xa4, 0xc5, 0xca, 0x37, 0x49, 0xee, - 0xa1, 0xaa, 0x2d, 0xf6, 0x98, 0x8d, 0x48, 0x03, 0x2a, 0x43, 0x1a, 0x0d, 0x32, 0x2b, 0xd4, 0x99, - 0x2c, 0xa4, 0x2a, 0x3c, 0x33, 0xc0, 0x52, 0x67, 0x85, 0xbc, 0x05, 0xd5, 0x13, 0xfa, 0x45, 0xc2, - 0x7b, 0x43, 0x1a, 0x29, 0x3d, 0x6a, 0x4a, 0x8f, 0xca, 0x03, 0x99, 0xf0, 0x6c, 0xcc, 0x3f, 0xa6, - 0x11, 0x62, 0xc3, 0x58, 0x61, 0x4b, 0x33, 0x58, 0x99, 0xf0, 0x6c, 0xcc, 0x4b, 0x6c, 0x03, 0x2a, - 0x7d, 0x2a, 0xfc, 0x27, 0x53, 0x56, 0x9b, 0x85, 0xa4, 0xa5, 0x0f, 0xe2, 0x54, 0xa0, 0x5f, 0x17, - 0x2d, 0x36, 0x8f, 0x66, 0x7d, 0x76, 0xd7, 0xce, 0x7f, 0x6f, 0x2e, 0x9c, 0x8f, 0x9b, 0xc6, 0x2f, - 0xe3, 0xa6, 0xf1, 0xeb, 0xb8, 0x69, 0xfc, 0x36, 0x6e, 0x1a, 0xdf, 0xfd, 0xd1, 0x5c, 0xf8, 0xcc, - 0x52, 0x22, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x57, 0x9b, 0xfd, 0x51, 0x92, 0x0a, 0x00, 0x00, + // 1100 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x6f, 0x1b, 0x45, + 0x14, 0xce, 0xda, 0xeb, 0x78, 0xfd, 0x12, 0x93, 0x7a, 0x04, 0x65, 0x65, 0x84, 0x9d, 0x2c, 0x54, + 0x2a, 0x3f, 0x94, 0xa6, 0x46, 0x56, 0x95, 0xa0, 0x02, 0x71, 0x43, 0xa5, 0x50, 0x5a, 0x45, 0x9b, + 0xd0, 0x03, 0x17, 0x6b, 0xb2, 0x33, 0xb8, 0x4b, 0x37, 0xbb, 0x66, 0x76, 0x9c, 0xc6, 0x77, 0x24, + 0x0e, 0xa8, 0x12, 0x47, 0x8e, 0xb9, 0xf4, 0x3f, 0xe0, 0xc0, 0x9f, 0x10, 0x71, 0xe2, 0xc8, 0x29, + 0x82, 0x70, 0xe1, 0xcc, 0x31, 0x27, 0x34, 0x6f, 0x67, 0xd6, 0xeb, 0xd4, 0x95, 0x48, 0x91, 0xb8, + 0x8d, 0xbf, 0xf7, 0x7d, 0x6f, 0xdf, 0xbc, 0xf7, 0xe6, 0x3d, 0xc3, 0x55, 0x91, 0xd0, 0xe0, 0xd1, + 0x70, 0xff, 0xc6, 0x01, 0x97, 0x94, 0x51, 0x49, 0x57, 0x87, 0x22, 0x91, 0x09, 0x69, 0x04, 0x49, + 0xf0, 0x18, 0x6d, 0xab, 0x9a, 0xd1, 0x6c, 0x8e, 0x64, 0x18, 0xdd, 0x18, 0xc5, 0x82, 0xa7, 0x49, + 0x74, 0xc8, 0x59, 0x9f, 0x32, 0x26, 0x32, 0x7a, 0xf3, 0xd5, 0x41, 0x32, 0x48, 0xf0, 0x78, 0x43, + 0x9d, 0x32, 0xd4, 0xfb, 0x18, 0x60, 0x53, 0x4a, 0x11, 0xee, 0x8f, 0x24, 0x4f, 0xc9, 0x7b, 0x50, + 0xa1, 0x52, 0x8a, 0xd4, 0xb5, 0x96, 0xcb, 0xd7, 0x6b, 0xbd, 0xd7, 0xfe, 0x3e, 0x6d, 0x37, 0xc6, + 0xf4, 0x20, 0xda, 0xf0, 0x10, 0x7e, 0xff, 0xab, 0x28, 0x79, 0xe2, 0xf9, 0x19, 0x67, 0xc3, 0xfe, + 0xf1, 0xb8, 0x3d, 0xe7, 0x7d, 0x67, 0x41, 0xc3, 0xe7, 0xc3, 0x28, 0x0c, 0xa8, 0x0c, 0x93, 0x78, + 0x8f, 0x8a, 0x01, 0x97, 0xe4, 0x26, 0x54, 0xe3, 0x84, 0xf1, 0x7e, 0xc8, 0x5c, 0x6b, 0xd9, 0xba, + 0x5e, 0xe9, 0xb9, 0x27, 0xa7, 0xed, 0xb9, 0xb3, 0xd3, 0xf6, 0xfc, 0x83, 0x84, 0xf1, 0xed, 0xad, + 0xf3, 0xfc, 0xe4, 0xcf, 0x2b, 0xe2, 0x36, 0x23, 0x5d, 0x70, 0x52, 0x99, 0x08, 0xd4, 0x94, 0x50, + 0xd3, 0xd4, 0x9a, 0xea, 0xae, 0xc2, 0x51, 0x64, 0x8e, 0x7e, 0x15, 0xb9, 0xdb, 0x6c, 0xc3, 0x51, + 0x51, 0xfc, 0x75, 0xdc, 0xb6, 0xbc, 0x5f, 0x26, 0x91, 0x6c, 0xf1, 0x34, 0x10, 0xe1, 0x50, 0x26, + 0xe2, 0xff, 0x8b, 0x84, 0xdc, 0x06, 0x10, 0xd9, 0xe7, 0x95, 0xb0, 0x8c, 0xc2, 0x96, 0x16, 0xd6, + 0x74, 0x60, 0x28, 0x9d, 0xfc, 0xf0, 0x6b, 0x5a, 0xb1, 0xcd, 0x36, 0x16, 0xd5, 0x45, 0x7e, 0x3e, + 0x6e, 0x5b, 0x78, 0x99, 0xef, 0x2d, 0x58, 0x34, 0x34, 0xc6, 0x63, 0xa9, 0x82, 0x12, 0x34, 0x1e, + 0xe4, 0x17, 0x29, 0x4f, 0x82, 0xf2, 0x15, 0x9e, 0x05, 0xa5, 0x8f, 0x7e, 0x15, 0xb9, 0xdb, 0x8c, + 0x6c, 0x41, 0x55, 0x7f, 0x02, 0xaf, 0xb2, 0xd0, 0x79, 0x7b, 0xf5, 0xb9, 0xb6, 0x59, 0x7d, 0x2e, + 0x6b, 0x3d, 0x5b, 0xf9, 0xf6, 0x8d, 0xd4, 0xfb, 0xa9, 0x04, 0x4b, 0xe8, 0xba, 0x90, 0xd8, 0x97, + 0x0c, 0xe8, 0x1a, 0xd4, 0x52, 0x49, 0x85, 0xec, 0x3f, 0xe6, 0x63, 0x0c, 0x69, 0xb1, 0xe7, 0x9c, + 0x9f, 0xb6, 0x6d, 0xff, 0x1e, 0x1f, 0xfb, 0x0e, 0x9a, 0xee, 0xf1, 0x31, 0x59, 0x81, 0x2a, 0x8f, + 0x19, 0x92, 0xca, 0x17, 0x48, 0xf3, 0x3c, 0x66, 0x8a, 0x72, 0x17, 0x1c, 0x1d, 0x5f, 0xea, 0xda, + 0xcb, 0xe5, 0x4b, 0xde, 0x2d, 0xd7, 0x92, 0xcf, 0x60, 0x29, 0xe6, 0x47, 0xb2, 0x5f, 0x28, 0x5e, + 0x05, 0x8b, 0xe7, 0xe9, 0xfb, 0xd4, 0x1f, 0xf0, 0x23, 0xf9, 0x82, 0x02, 0xd6, 0xe3, 0x82, 0xed, + 0x62, 0x11, 0x9f, 0x59, 0xb0, 0xb0, 0xc3, 0x45, 0xc0, 0x63, 0x19, 0x46, 0x3c, 0x25, 0x57, 0xa1, + 0x3c, 0xbc, 0xb9, 0x86, 0xd9, 0xb2, 0x74, 0x18, 0x0a, 0x40, 0xbc, 0xd3, 0xc5, 0x6c, 0x4c, 0xf0, + 0x4e, 0x17, 0xf1, 0xee, 0x1a, 0x26, 0x60, 0x82, 0x77, 0x33, 0xfe, 0xad, 0xae, 0x6b, 0x4f, 0xe1, + 0xb7, 0x32, 0xfe, 0xfa, 0x1a, 0x46, 0x3f, 0xc1, 0xd7, 0xd7, 0x88, 0x0b, 0xf6, 0xf0, 0x3e, 0x3d, + 0x72, 0xe7, 0x0b, 0x06, 0x44, 0xf4, 0x1b, 0x3e, 0x2f, 0x43, 0x1d, 0xdb, 0xf9, 0x0e, 0x1d, 0xd2, + 0x20, 0x94, 0x63, 0xb2, 0x0c, 0x4e, 0xa0, 0xcf, 0xba, 0xb8, 0x3a, 0x6b, 0x06, 0x25, 0x1e, 0xd4, + 0xe8, 0x21, 0x0d, 0x23, 0xba, 0x1f, 0x71, 0x8c, 0xdc, 0x50, 0x26, 0x30, 0xb9, 0x06, 0x0b, 0x59, + 0x8b, 0x04, 0xc9, 0x28, 0x96, 0xfa, 0x49, 0x64, 0x2c, 0x40, 0xc3, 0x1d, 0x85, 0x2b, 0x5a, 0xc4, + 0x69, 0x6a, 0x68, 0x76, 0x91, 0x86, 0x86, 0x8c, 0xb6, 0x06, 0x8d, 0x27, 0x22, 0x94, 0x3c, 0xed, + 0x0f, 0xb9, 0xe8, 0xa7, 0x3c, 0x48, 0x62, 0x36, 0x75, 0xd7, 0xa5, 0xcc, 0xbc, 0xc3, 0xc5, 0x2e, + 0x1a, 0xc9, 0x0e, 0x34, 0xf6, 0xc7, 0x46, 0x60, 0x9e, 0xc1, 0x3c, 0x3e, 0x83, 0xd6, 0x8c, 0x56, + 0x29, 0x94, 0xca, 0x78, 0x44, 0xf9, 0x0e, 0x17, 0xba, 0xc2, 0xc4, 0x07, 0x52, 0x88, 0xc1, 0xb8, + 0xac, 0x5e, 0xc2, 0xe5, 0x95, 0x3c, 0x48, 0xe3, 0xd3, 0x05, 0x7b, 0x94, 0x72, 0xe6, 0x3a, 0x85, + 0x24, 0x22, 0x42, 0xde, 0x81, 0x7a, 0x94, 0x0c, 0xc2, 0x80, 0x46, 0x7d, 0x0c, 0xc4, 0xad, 0x15, + 0x28, 0x8b, 0xda, 0xd4, 0x53, 0x16, 0xd2, 0x01, 0xf2, 0xcd, 0x88, 0x8b, 0x70, 0x3a, 0x3b, 0x50, + 0xc8, 0xce, 0x15, 0x6d, 0xcf, 0xd3, 0xa3, 0x8b, 0xff, 0xb4, 0x0c, 0xaf, 0xa8, 0x01, 0xf8, 0xdf, + 0x66, 0xe6, 0x47, 0x50, 0x55, 0xbb, 0x86, 0xa7, 0xa9, 0x9e, 0x33, 0xc5, 0x6c, 0xa8, 0xad, 0xb4, + 0xfa, 0x45, 0xbe, 0x95, 0x36, 0x19, 0xcb, 0x27, 0x8c, 0x16, 0x91, 0x75, 0xb3, 0x79, 0xca, 0xa8, + 0x7e, 0x73, 0x46, 0x2e, 0x27, 0x7b, 0x4a, 0x8b, 0x33, 0x05, 0xb9, 0x0d, 0x4e, 0x94, 0x04, 0x34, + 0x52, 0xbd, 0x6a, 0xa3, 0xfa, 0x8d, 0x19, 0xea, 0xcf, 0x35, 0xc5, 0x34, 0xb2, 0x91, 0x90, 0xbb, + 0x50, 0xdf, 0xe5, 0xe2, 0x90, 0x8b, 0x87, 0x5c, 0xa4, 0x61, 0x12, 0x63, 0x4b, 0x2d, 0x74, 0x9a, + 0x33, 0x7c, 0x68, 0x86, 0x76, 0x31, 0x2d, 0x23, 0x2b, 0x50, 0xdb, 0x1f, 0x85, 0x11, 0xeb, 0x4b, + 0x3a, 0xc0, 0x26, 0xab, 0x99, 0x4f, 0x21, 0xbc, 0x47, 0x07, 0xe4, 0x2d, 0x00, 0x1c, 0x70, 0x6a, + 0x31, 0x4b, 0xec, 0x9a, 0xfc, 0xd1, 0x68, 0x7c, 0x53, 0x7a, 0xdf, 0x96, 0x60, 0x09, 0x1f, 0xe3, + 0xf4, 0xac, 0xcd, 0x37, 0x92, 0xf5, 0xef, 0x37, 0x52, 0x9e, 0xd4, 0xd2, 0xa5, 0x93, 0xfa, 0x21, + 0xd8, 0xaa, 0xb2, 0xba, 0x1c, 0x2b, 0x33, 0x94, 0xd3, 0x3d, 0x63, 0xfa, 0x56, 0x89, 0x48, 0xaf, + 0x30, 0x3d, 0xb2, 0x8a, 0x2c, 0xcf, 0x70, 0x30, 0x35, 0x71, 0x2e, 0xce, 0x17, 0xef, 0xa9, 0x05, + 0x0d, 0x9d, 0x06, 0xca, 0x7c, 0x33, 0xab, 0x5f, 0x32, 0x11, 0x9b, 0x85, 0x55, 0x51, 0xc2, 0x55, + 0xd1, 0x7e, 0xf1, 0xaa, 0xc0, 0x7d, 0x7b, 0x71, 0x4b, 0x78, 0x9f, 0x82, 0x63, 0x5a, 0x88, 0x7c, + 0x00, 0x15, 0x19, 0x72, 0xfd, 0x37, 0x69, 0xa1, 0xf3, 0xfa, 0x0c, 0x5f, 0x7b, 0x21, 0x37, 0x39, + 0xc9, 0xb8, 0xfa, 0xb5, 0x7d, 0x02, 0xb6, 0x32, 0xa9, 0x51, 0xad, 0x76, 0x9b, 0x55, 0xe8, 0x13, + 0x05, 0x90, 0x26, 0x54, 0x0e, 0x69, 0x34, 0xca, 0x46, 0xaa, 0xb1, 0x64, 0x90, 0xf6, 0xf0, 0xcc, + 0x82, 0xaa, 0xe9, 0xb9, 0x77, 0xa1, 0x76, 0x40, 0xbf, 0x4e, 0x44, 0xff, 0x90, 0x46, 0x3a, 0x1f, + 0x75, 0x9d, 0x8f, 0xca, 0x7d, 0x65, 0xf0, 0x1d, 0xb4, 0x3f, 0xa4, 0x11, 0x72, 0xc3, 0x58, 0x73, + 0x4b, 0x17, 0xb8, 0xca, 0xe0, 0x3b, 0x68, 0x57, 0xdc, 0x26, 0x54, 0x86, 0x54, 0x06, 0x8f, 0xa6, + 0x46, 0x76, 0x06, 0xa9, 0xd5, 0x30, 0x8a, 0x53, 0x89, 0x73, 0xbf, 0x38, 0xaa, 0x73, 0x34, 0x8b, + 0xb3, 0xb7, 0x72, 0xf2, 0x47, 0x6b, 0xee, 0xe4, 0xac, 0x65, 0xfd, 0x7a, 0xd6, 0xb2, 0x7e, 0x3b, + 0x6b, 0x59, 0xbf, 0x9f, 0xb5, 0xac, 0x1f, 0xfe, 0x6c, 0xcd, 0x7d, 0x59, 0xd5, 0x49, 0xfa, 0x27, + 0x00, 0x00, 0xff, 0xff, 0x0b, 0xba, 0xf4, 0xde, 0xda, 0x0a, 0x00, 0x00, } diff --git a/pkg/roachpb/metadata.proto b/pkg/roachpb/metadata.proto index 21441f352a15..e685352c278d 100644 --- a/pkg/roachpb/metadata.proto +++ b/pkg/roachpb/metadata.proto @@ -151,6 +151,8 @@ message NodeDescriptor { optional Attributes attrs = 3 [(gogoproto.nullable) = false]; optional Locality locality = 4 [(gogoproto.nullable) = false]; optional Version ServerVersion = 5 [(gogoproto.nullable) = false]; + optional string build_tag = 6 [(gogoproto.nullable) = false]; + optional int64 started_at = 7 [(gogoproto.nullable) = false]; } // StoreDescriptor holds store information including store attributes, node diff --git a/pkg/server/node.go b/pkg/server/node.go index 50f74617fa97..a3b5651bd00f 100644 --- a/pkg/server/node.go +++ b/pkg/server/node.go @@ -28,6 +28,7 @@ import ( "github.com/pkg/errors" "github.com/cockroachdb/cockroach/pkg/base" + "github.com/cockroachdb/cockroach/pkg/build" "github.com/cockroachdb/cockroach/pkg/gossip" "github.com/cockroachdb/cockroach/pkg/internal/client" "github.com/cockroachdb/cockroach/pkg/keys" @@ -424,12 +425,16 @@ func (n *Node) start( span.Finish() nodeID = newID } + + n.startedAt = n.storeCfg.Clock.Now().WallTime n.Descriptor = roachpb.NodeDescriptor{ NodeID: nodeID, Address: util.MakeUnresolvedAddr(addr.Network(), addr.String()), Attrs: attrs, Locality: locality, ServerVersion: n.storeCfg.Settings.Version.ServerVersion, + BuildTag: build.GetInfo().Tag, + StartedAt: n.startedAt, } // Gossip the node descriptor to make this node addressable by node ID. @@ -520,8 +525,6 @@ func (n *Node) start( } } - n.startedAt = n.storeCfg.Clock.Now().WallTime - n.startComputePeriodicMetrics(n.stopper, DefaultMetricsSampleInterval) // Be careful about moving this line above `startStores`; store migrations rely // on the fact that the cluster version has not been updated via Gossip (we diff --git a/pkg/server/node_test.go b/pkg/server/node_test.go index 71e0bef860e0..3cf0efab5d65 100644 --- a/pkg/server/node_test.go +++ b/pkg/server/node_test.go @@ -437,7 +437,7 @@ func compareNodeStatus( // Descriptor values should be exactly equal to expected. if a, e := nodeStatus.Desc, expectedNodeStatus.Desc; !reflect.DeepEqual(a, e) { - t.Errorf("%d: Descriptor does not match expected.\nexpected: %s\nactual: %s", testNumber, e, a) + t.Errorf("%d: Descriptor does not match expected.\nexpected: %s\nactual: %s", testNumber, &e, &a) } // ======================================== diff --git a/pkg/sql/crdb_internal.go b/pkg/sql/crdb_internal.go index d242e5f0a724..3f8aa42089c3 100644 --- a/pkg/sql/crdb_internal.go +++ b/pkg/sql/crdb_internal.go @@ -1742,7 +1742,11 @@ CREATE TABLE crdb_internal.gossip_nodes ( address STRING NOT NULL, attrs JSON NOT NULL, locality JSON NOT NULL, - server_version STRING NOT NULL + server_version STRING NOT NULL, + build_tag STRING NOT NULL, + started_at TIMESTAMP NOT NULL, + ranges INT NOT NULL, + leases INT NOT NULL ) `, populate: func(ctx context.Context, p *planner, _ *DatabaseDescriptor, addRow func(...tree.Datum) error) error { @@ -1772,6 +1776,32 @@ CREATE TABLE crdb_internal.gossip_nodes ( return descriptors[i].NodeID < descriptors[j].NodeID }) + type nodeStats struct { + ranges int32 + leases int32 + } + + stats := make(map[roachpb.NodeID]nodeStats) + if err := g.IterateInfos(gossip.KeyStorePrefix, func(key string, i gossip.Info) error { + bytes, err := i.Value.GetBytes() + if err != nil { + return errors.Wrapf(err, "failed to extract bytes for key %q", key) + } + + var desc roachpb.StoreDescriptor + if err := protoutil.Unmarshal(bytes, &desc); err != nil { + return errors.Wrapf(err, "failed to parse value for key %q", key) + } + + s := stats[desc.Node.NodeID] + s.ranges += desc.Capacity.RangeCount + s.leases += desc.Capacity.LeaseCount + stats[desc.Node.NodeID] = s + return nil + }); err != nil { + return err + } + for _, d := range descriptors { attrs := json.NewArrayBuilder(len(d.Attrs.Attrs)) for _, a := range d.Attrs.Attrs { @@ -1790,6 +1820,10 @@ CREATE TABLE crdb_internal.gossip_nodes ( tree.NewDJSON(attrs.Build()), tree.NewDJSON(locality.Build()), tree.NewDString(d.ServerVersion.String()), + tree.NewDString(d.BuildTag), + tree.MakeDTimestamp(timeutil.Unix(0, d.StartedAt), time.Microsecond), + tree.NewDInt(tree.DInt(stats[d.NodeID].ranges)), + tree.NewDInt(tree.DInt(stats[d.NodeID].leases)), ); err != nil { return err } @@ -1806,16 +1840,27 @@ CREATE TABLE crdb_internal.gossip_liveness ( epoch INT NOT NULL, expiration STRING NOT NULL, draining BOOL NOT NULL, - decommissioning BOOL NOT NULL + decommissioning BOOL NOT NULL, + updated_at TIMESTAMP ) `, populate: func(ctx context.Context, p *planner, _ *DatabaseDescriptor, addRow func(...tree.Datum) error) error { + // ATTENTION: This contents of this table should only access gossip data + // which is highly available. DO NOT CALL functions which require the + // cluster to be healthy, such as StatusServer.Nodes(). + if err := p.RequireSuperUser(ctx, "read crdb_internal.gossip_liveness"); err != nil { return err } g := p.ExecCfg().Gossip - var livenesses []storage.Liveness + + type nodeInfo struct { + liveness storage.Liveness + updatedAt int64 + } + + var nodes []nodeInfo if err := g.IterateInfos(gossip.KeyNodeLivenessPrefix, func(key string, i gossip.Info) error { bytes, err := i.Value.GetBytes() if err != nil { @@ -1826,23 +1871,29 @@ CREATE TABLE crdb_internal.gossip_liveness ( if err := protoutil.Unmarshal(bytes, &l); err != nil { return errors.Wrapf(err, "failed to parse value for key %q", key) } - livenesses = append(livenesses, l) + nodes = append(nodes, nodeInfo{ + liveness: l, + updatedAt: i.OrigStamp, + }) return nil }); err != nil { return err } - sort.Slice(livenesses, func(i, j int) bool { - return livenesses[i].NodeID < livenesses[j].NodeID + sort.Slice(nodes, func(i, j int) bool { + return nodes[i].liveness.NodeID < nodes[j].liveness.NodeID }) - for _, l := range livenesses { + for i := range nodes { + n := &nodes[i] + l := &n.liveness if err := addRow( tree.NewDInt(tree.DInt(l.NodeID)), tree.NewDInt(tree.DInt(l.Epoch)), tree.NewDString(l.Expiration.String()), tree.MakeDBool(tree.DBool(l.Draining)), tree.MakeDBool(tree.DBool(l.Decommissioning)), + tree.MakeDTimestamp(timeutil.Unix(0, n.updatedAt), time.Microsecond), ); err != nil { return err } diff --git a/pkg/sql/logictest/testdata/planner_test/explain b/pkg/sql/logictest/testdata/planner_test/explain index 0143b6918d17..43b8756fbf7e 100644 --- a/pkg/sql/logictest/testdata/planner_test/explain +++ b/pkg/sql/logictest/testdata/planner_test/explain @@ -223,7 +223,7 @@ sort · · ├── render · · │ └── filter · · │ └── values · · - │ size 17 columns, 901 rows + │ size 17 columns, 906 rows └── render · · └── filter · · └── values · · diff --git a/pkg/sql/opt/exec/execbuilder/testdata/explain b/pkg/sql/opt/exec/execbuilder/testdata/explain index 6ff9cbe85d72..9ec239317080 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/explain +++ b/pkg/sql/opt/exec/execbuilder/testdata/explain @@ -216,7 +216,7 @@ sort · · ├── render · · │ └── filter · · │ └── values · · - │ size 17 columns, 901 rows + │ size 17 columns, 906 rows └── render · · └── filter · · └── values · ·