Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server: add NodeIds to DatabaseDetails and TableStats responses #69788

Merged
merged 1 commit into from
Sep 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/generated/http/full.md
Original file line number Diff line number Diff line change
Expand Up @@ -3596,6 +3596,7 @@ zone configuration, and size statistics for a database.
| missing_tables | [DatabaseDetailsResponse.Stats.MissingTable](#cockroach.server.serverpb.DatabaseDetailsResponse-cockroach.server.serverpb.DatabaseDetailsResponse.Stats.MissingTable) | repeated | A list of tables that exist in the database, but for which stats could not be loaded due to failures during this request. | [reserved](#support-status) |
| range_count | [int64](#cockroach.server.serverpb.DatabaseDetailsResponse-int64) | | The number of ranges, as determined from a query of range meta keys, across all tables. | [reserved](#support-status) |
| approximate_disk_bytes | [uint64](#cockroach.server.serverpb.DatabaseDetailsResponse-uint64) | | An approximation of the disk space (in bytes) used for all replicas of all tables across the cluster. | [reserved](#support-status) |
| node_ids | [int32](#cockroach.server.serverpb.DatabaseDetailsResponse-int32) | repeated | node_ids is the ordered list of node ids on which data is stored. | [reserved](#support-status) |



Expand Down Expand Up @@ -3767,6 +3768,7 @@ about a table.
| stats | [cockroach.storage.enginepb.MVCCStats](#cockroach.server.serverpb.TableStatsResponse-cockroach.storage.enginepb.MVCCStats) | | stats is the summation of MVCCStats for all replicas of this table across the cluster. | [reserved](#support-status) |
| approximate_disk_bytes | [uint64](#cockroach.server.serverpb.TableStatsResponse-uint64) | | approximate_disk_bytes is an approximation of the disk space (in bytes) used for all replicas of this table across the cluster. | [reserved](#support-status) |
| missing_nodes | [TableStatsResponse.MissingNode](#cockroach.server.serverpb.TableStatsResponse-cockroach.server.serverpb.TableStatsResponse.MissingNode) | repeated | A list of nodes which should contain data for this table (according to cluster metadata), but could not be contacted during this request. | [reserved](#support-status) |
| node_ids | [int32](#cockroach.server.serverpb.TableStatsResponse-int32) | repeated | node_ids is the ordered list of node ids on which the table data is stored. | [reserved](#support-status) |



Expand Down Expand Up @@ -3846,6 +3848,7 @@ about a table.
| stats | [cockroach.storage.enginepb.MVCCStats](#cockroach.server.serverpb.NonTableStatsResponse-cockroach.storage.enginepb.MVCCStats) | | stats is the summation of MVCCStats for all replicas of this table across the cluster. | [reserved](#support-status) |
| approximate_disk_bytes | [uint64](#cockroach.server.serverpb.NonTableStatsResponse-uint64) | | approximate_disk_bytes is an approximation of the disk space (in bytes) used for all replicas of this table across the cluster. | [reserved](#support-status) |
| missing_nodes | [TableStatsResponse.MissingNode](#cockroach.server.serverpb.NonTableStatsResponse-cockroach.server.serverpb.TableStatsResponse.MissingNode) | repeated | A list of nodes which should contain data for this table (according to cluster metadata), but could not be contacted during this request. | [reserved](#support-status) |
| node_ids | [int32](#cockroach.server.serverpb.NonTableStatsResponse-int32) | repeated | node_ids is the ordered list of node ids on which the table data is stored. | [reserved](#support-status) |



Expand Down Expand Up @@ -3880,6 +3883,7 @@ about a table.
| stats | [cockroach.storage.enginepb.MVCCStats](#cockroach.server.serverpb.NonTableStatsResponse-cockroach.storage.enginepb.MVCCStats) | | stats is the summation of MVCCStats for all replicas of this table across the cluster. | [reserved](#support-status) |
| approximate_disk_bytes | [uint64](#cockroach.server.serverpb.NonTableStatsResponse-uint64) | | approximate_disk_bytes is an approximation of the disk space (in bytes) used for all replicas of this table across the cluster. | [reserved](#support-status) |
| missing_nodes | [TableStatsResponse.MissingNode](#cockroach.server.serverpb.NonTableStatsResponse-cockroach.server.serverpb.TableStatsResponse.MissingNode) | repeated | A list of nodes which should contain data for this table (according to cluster metadata), but could not be contacted during this request. | [reserved](#support-status) |
| node_ids | [int32](#cockroach.server.serverpb.NonTableStatsResponse-int32) | repeated | node_ids is the ordered list of node ids on which the table data is stored. | [reserved](#support-status) |



Expand Down
22 changes: 22 additions & 0 deletions pkg/server/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,8 @@ func (s *adminServer) getDatabaseStats(
}
}

// Track all nodes storing databases.
nodeIDs := make(map[roachpb.NodeID]struct{})
for i := 0; i < len(tableSpans); i++ {
select {
case response := <-responses:
Expand All @@ -570,12 +572,23 @@ func (s *adminServer) getDatabaseStats(
} else {
stats.RangeCount += response.resp.RangeCount
stats.ApproximateDiskBytes += response.resp.ApproximateDiskBytes
for _, id := range response.resp.NodeIDs {
nodeIDs[id] = struct{}{}
}
}
case <-ctx.Done():
return nil, ctx.Err()
}
}

stats.NodeIDs = make([]roachpb.NodeID, 0, len(nodeIDs))
for id := range nodeIDs {
stats.NodeIDs = append(stats.NodeIDs, id)
}
sort.Slice(stats.NodeIDs, func(i, j int) bool {
return stats.NodeIDs[i] < stats.NodeIDs[j]
})

return &stats, nil
}

Expand Down Expand Up @@ -1058,9 +1071,18 @@ func (s *adminServer) statsForSpan(
}
}

nodeIDList := make([]roachpb.NodeID, 0, len(nodeIDs))
for id := range nodeIDs {
nodeIDList = append(nodeIDList, id)
}
sort.Slice(nodeIDList, func(i, j int) bool {
return nodeIDList[i] < nodeIDList[j]
})

// Construct TableStatsResponse by sending an RPC to every node involved.
tableStatResponse := serverpb.TableStatsResponse{
NodeCount: int64(len(nodeIDs)),
NodeIDs: nodeIDList,
// TODO(mrtracy): The "RangeCount" returned by TableStats is more
// accurate than the "RangeCount" returned by TableDetails, because this
// method always consistently queries the meta2 key range for the table;
Expand Down
5 changes: 5 additions & 0 deletions pkg/server/admin_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ func TestAdminAPIDatabaseDetails(t *testing.T) {
var resp serverpb.DatabaseDetailsResponse
require.NoError(t, serverutils.GetJSONProto(s, "/_admin/v1/databases/test?include_stats=true", &resp))

nodeIDs := []roachpb.NodeID{1, 2, 3}
assert.Equal(t, int64(1), resp.Stats.RangeCount, "RangeCount")
assert.Equal(t, nodeIDs, resp.Stats.NodeIDs, "NodeIDs")

// TODO(todd): Find a way to produce a non-zero value here that doesn't require writing a million rows.
// Giving the test nodes on-disk stores (StoreSpec{inMemory: false, Path: "..."}) didn't work and was slow.
Expand Down Expand Up @@ -174,6 +176,9 @@ func TestAdminAPITableStats(t *testing.T) {
if len(tsResponse.MissingNodes) != 1 {
t.Errorf("expected one missing node, found %v", tsResponse.MissingNodes)
}
if len(tsResponse.NodeIDs) == 0 {
t.Error("expected at least one node in NodeIds list")
}

// Call TableStats with a very low timeout. This tests that fan-out queries
// do not leak goroutines if the calling context is abandoned.
Expand Down
Loading