diff --git a/pkg/server/admin.go b/pkg/server/admin.go index ba0d7035df6b..6bb1a62ba58a 100644 --- a/pkg/server/admin.go +++ b/pkg/server/admin.go @@ -67,6 +67,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/util/mon" "github.com/cockroachdb/cockroach/pkg/util/protoutil" "github.com/cockroachdb/cockroach/pkg/util/quotapool" + "github.com/cockroachdb/cockroach/pkg/util/rangedesc" "github.com/cockroachdb/cockroach/pkg/util/safesql" "github.com/cockroachdb/cockroach/pkg/util/stop" "github.com/cockroachdb/cockroach/pkg/util/timeutil" @@ -1336,7 +1337,7 @@ func (s *adminServer) statsForSpan( // Get a list of nodeIDs, range counts, and replica counts per node // for the specified span. nodeIDs, rangeCount, replCounts, err := getNodeIDsRangeCountReplCountForSpan( - ctx, s.distSender, rSpan, + ctx, s.db, rSpan, s.st, ) if err != nil { return nil, err @@ -1451,23 +1452,29 @@ func (s *adminServer) statsForSpan( // Returns the list of node ids, range count, // and replica count for the specified span. func getNodeIDsRangeCountReplCountForSpan( - ctx context.Context, ds *kvcoord.DistSender, rSpan roachpb.RSpan, + ctx context.Context, db *kv.DB, rSpan roachpb.RSpan, st *cluster.Settings, ) (nodeIDList []roachpb.NodeID, rangeCount int64, replCounts map[roachpb.NodeID]int64, _ error) { nodeIDs := make(map[roachpb.NodeID]struct{}) replCountForNodeID := make(map[roachpb.NodeID]int64) - ri := kvcoord.MakeRangeIterator(ds) - ri.Seek(ctx, rSpan.Key, kvcoord.Ascending) - for ; ri.Valid(); ri.Next(ctx) { - rangeCount++ - for _, repl := range ri.Desc().Replicas().Descriptors() { - replCountForNodeID[repl.NodeID]++ - nodeIDs[repl.NodeID] = struct{}{} - } - if !ri.NeedAnother(rSpan) { - break + scanner := rangedesc.NewScanner(db) + pageSize := int(roachpb.RangeDescPageSize.Get(&st.SV)) + err := scanner.Scan(ctx, pageSize, func() { + // If the underlying txn fails and needs to be retried, + // clear the nodeIDs we've collected so far. + nodeIDs = map[roachpb.NodeID]struct{}{} + replCountForNodeID = map[roachpb.NodeID]int64{} + rangeCount = 0 + }, rSpan.AsRawSpanWithNoLocals(), func(scanned ...roachpb.RangeDescriptor) error { + for _, desc := range scanned { + rangeCount++ + for _, repl := range desc.Replicas().Descriptors() { + nodeIDs[repl.NodeID] = struct{}{} + replCountForNodeID[repl.NodeID]++ + } } - } - if err := ri.Error(); err != nil { + return nil + }) + if err != nil { return nil, 0, nil, err }