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/api: add the api to show the regions in subtree by type #8101

Merged
merged 4 commits into from
Apr 30, 2024
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
54 changes: 54 additions & 0 deletions pkg/core/region.go
Original file line number Diff line number Diff line change
Expand Up @@ -1541,6 +1541,60 @@
return regions
}

// SubTreeRegionType is the type of sub tree region.
type SubTreeRegionType string

const (
// AllInSubTree is all sub trees.
AllInSubTree SubTreeRegionType = "all"
// LeaderInSubTree is the leader sub tree.
LeaderInSubTree SubTreeRegionType = "leader"
// FollowerInSubTree is the follower sub tree.
FollowerInSubTree SubTreeRegionType = "follower"
// LearnerInSubTree is the learner sub tree.
LearnerInSubTree SubTreeRegionType = "learner"
// WitnessInSubTree is the witness sub tree.
WitnessInSubTree SubTreeRegionType = "witness"
// PendingPeerInSubTree is the pending peer sub tree.
PendingPeerInSubTree SubTreeRegionType = "pending"
)

// GetStoreRegions gets all RegionInfo with a given storeID
func (r *RegionsInfo) GetStoreRegionsByTypeInSubTree(storeID uint64, typ SubTreeRegionType) ([]*RegionInfo, error) {
r.st.RLock()
var regions []*RegionInfo
switch typ {
case LeaderInSubTree:
if leaders, ok := r.leaders[storeID]; ok {
regions = leaders.scanRanges()
}
case FollowerInSubTree:
if followers, ok := r.followers[storeID]; ok {
regions = followers.scanRanges()
}
case LearnerInSubTree:
if learners, ok := r.learners[storeID]; ok {
regions = learners.scanRanges()
}
case WitnessInSubTree:
if witnesses, ok := r.witnesses[storeID]; ok {
regions = witnesses.scanRanges()

Check warning on line 1581 in pkg/core/region.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/region.go#L1581

Added line #L1581 was not covered by tests
}
case PendingPeerInSubTree:
if pendingPeers, ok := r.pendingPeers[storeID]; ok {
regions = pendingPeers.scanRanges()

Check warning on line 1585 in pkg/core/region.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/region.go#L1585

Added line #L1585 was not covered by tests
}
case AllInSubTree:
r.st.RUnlock()
return r.GetStoreRegions(storeID), nil
default:
return nil, errors.Errorf("unknown sub tree region type %v", typ)

Check warning on line 1591 in pkg/core/region.go

View check run for this annotation

Codecov / codecov/patch

pkg/core/region.go#L1590-L1591

Added lines #L1590 - L1591 were not covered by tests
}
nolouch marked this conversation as resolved.
Show resolved Hide resolved

r.st.RUnlock()
return regions, nil
}

// GetStoreLeaderRegionSize get total size of store's leader regions
func (r *RegionsInfo) GetStoreLeaderRegionSize(storeID uint64) int64 {
r.st.RLock()
Expand Down
2 changes: 2 additions & 0 deletions pkg/response/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ type StoreStatus struct {
RegionSize int64 `json:"region_size"`
LearnerCount int `json:"learner_count,omitempty"`
WitnessCount int `json:"witness_count,omitempty"`
PendingPeerCount int `json:"pending_peer_count,omitempty"`
SlowScore uint64 `json:"slow_score,omitempty"`
SlowTrend *SlowTrend `json:"slow_trend,omitempty"`
SendingSnapCount uint32 `json:"sending_snap_count,omitempty"`
Expand Down Expand Up @@ -117,6 +118,7 @@ func BuildStoreInfo(opt *sc.ScheduleConfig, store *core.StoreInfo) *StoreInfo {
SlowTrend: slowTrend,
SendingSnapCount: store.GetSendingSnapCount(),
ReceivingSnapCount: store.GetReceivingSnapCount(),
PendingPeerCount: store.GetPendingPeerCount(),
IsBusy: store.IsBusy(),
},
}
Expand Down
12 changes: 11 additions & 1 deletion server/api/region.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,17 @@
h.rd.JSON(w, http.StatusBadRequest, err.Error())
return
}
regions := rc.GetStoreRegions(uint64(id))
// get type from query
typ := r.URL.Query().Get("type")
if len(typ) == 0 {
typ = string(core.AllInSubTree)
}

regions, err := rc.GetStoreRegionsByTypeInSubTree(uint64(id), core.SubTreeRegionType(typ))
if err != nil {
h.rd.JSON(w, http.StatusBadRequest, err.Error())
return

Check warning on line 230 in server/api/region.go

View check run for this annotation

Codecov / codecov/patch

server/api/region.go#L229-L230

Added lines #L229 - L230 were not covered by tests
}
b, err := response.MarshalRegionsInfoJSON(r.Context(), regions)
if err != nil {
h.rd.JSON(w, http.StatusInternalServerError, err.Error())
Expand Down
5 changes: 5 additions & 0 deletions server/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -1198,6 +1198,11 @@
return c.core.GetStoreRegions(storeID)
}

// GetStoreRegions returns all regions' information with a given storeID.
func (c *RaftCluster) GetStoreRegionsByType(storeID uint64) []*core.RegionInfo {
return c.core.GetStoreRegions(storeID)

Check warning on line 1203 in server/cluster/cluster.go

View check run for this annotation

Codecov / codecov/patch

server/cluster/cluster.go#L1202-L1203

Added lines #L1202 - L1203 were not covered by tests
}

// RandLeaderRegions returns some random regions that has leader on the store.
func (c *RaftCluster) RandLeaderRegions(storeID uint64, ranges []core.KeyRange) []*core.RegionInfo {
return c.core.RandLeaderRegions(storeID, ranges)
Expand Down
3 changes: 3 additions & 0 deletions tools/pd-ctl/pdctl/command/region_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ func NewRegionWithStoreCommand() *cobra.Command {
Short: "show the regions of a specific store",
Run: showRegionWithStoreCommandFunc,
}
r.Flags().String("type", "all", "the type of the regions, could be 'all', 'leader', 'learner' or 'pending'")
return r
}

Expand All @@ -496,6 +497,8 @@ func showRegionWithStoreCommandFunc(cmd *cobra.Command, args []string) {
}
storeID := args[0]
prefix := regionsStorePrefix + "/" + storeID
flagType := cmd.Flag("type")
prefix += "?type=" + flagType.Value.String()
r, err := doRequest(cmd, prefix, http.MethodGet, http.Header{})
if err != nil {
cmd.Printf("Failed to get regions with the given storeID: %s\n", err)
Expand Down
12 changes: 11 additions & 1 deletion tools/pd-ctl/tests/region/region_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ func TestRegion(t *testing.T) {
)
defer cluster.Destroy()

getRegionsByType := func(storeID uint64, regionType core.SubTreeRegionType) []*core.RegionInfo {
regions, _ := leaderServer.GetRaftCluster().GetStoreRegionsByTypeInSubTree(storeID, regionType)
return regions
}

var testRegionsCases = []struct {
args []string
expect []*core.RegionInfo
Expand All @@ -118,7 +123,12 @@ func TestRegion(t *testing.T) {
{[]string{"region", "sibling", "2"}, leaderServer.GetAdjacentRegions(leaderServer.GetRegionInfoByID(2))},
// region store <store_id> command
{[]string{"region", "store", "1"}, leaderServer.GetStoreRegions(1)},
{[]string{"region", "store", "1"}, []*core.RegionInfo{r1, r2, r3, r4}},
{[]string{"region", "store", "1", "--type=leader"}, getRegionsByType(1, core.LeaderInSubTree)},
{[]string{"region", "store", "1", "--type=follower"}, getRegionsByType(1, core.FollowerInSubTree)},
{[]string{"region", "store", "1", "--type=learner"}, getRegionsByType(1, core.LearnerInSubTree)},
{[]string{"region", "store", "1", "--type=witness"}, getRegionsByType(1, core.WitnessInSubTree)},
{[]string{"region", "store", "1", "--type=pending"}, getRegionsByType(1, core.PendingPeerInSubTree)},
{[]string{"region", "store", "1", "--type=all"}, []*core.RegionInfo{r1, r2, r3, r4}},
// region check extra-peer command
{[]string{"region", "check", "extra-peer"}, []*core.RegionInfo{r1}},
// region check miss-peer command
Expand Down