From 15e438aaa6ddfb4748547e9fb43060e3012b255c Mon Sep 17 00:00:00 2001 From: disksing Date: Mon, 16 Apr 2018 18:24:31 +0800 Subject: [PATCH 1/2] pdctl, api, schedule: pdctl supports scatter region. --- pdctl/command/operator.go | 29 +++++++++++++++++++++++++++++ server/api/operator.go | 10 ++++++++++ server/handler.go | 19 +++++++++++++++++++ server/schedule/region_scatterer.go | 4 +++- 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/pdctl/command/operator.go b/pdctl/command/operator.go index 11bbbe70ced..b944e8086ce 100644 --- a/pdctl/command/operator.go +++ b/pdctl/command/operator.go @@ -80,6 +80,7 @@ func NewAddOperatorCommand() *cobra.Command { c.AddCommand(NewRemovePeerCommand()) c.AddCommand(NewMergeRegionCommand()) c.AddCommand(NewSplitRegionCommand()) + c.AddCommand(NewScatterRegionCommand()) return c } @@ -286,6 +287,34 @@ func splitRegionCommandFunc(cmd *cobra.Command, args []string) { postJSON(cmd, operatorsPrefix, input) } +// NewScatterRegionCommand returns a command to scatter a region. +func NewScatterRegionCommand() *cobra.Command { + c := &cobra.Command{ + Use: "scatter-region ", + Short: "scatter a region", + Run: scatterRegionCommandFunc, + } + return c +} + +func scatterRegionCommandFunc(cmd *cobra.Command, args []string) { + if len(args) != 1 { + fmt.Println(cmd.UsageString()) + return + } + + ids, err := parseUint64s(args) + if err != nil { + fmt.Println(err) + return + } + + input := make(map[string]interface{}) + input["name"] = cmd.Name() + input["region_id"] = ids[0] + postJSON(cmd, operatorsPrefix, input) +} + // NewRemoveOperatorCommand returns a command to remove operators. func NewRemoveOperatorCommand() *cobra.Command { c := &cobra.Command{ diff --git a/server/api/operator.go b/server/api/operator.go index d880615f971..2be9c52e7a8 100644 --- a/server/api/operator.go +++ b/server/api/operator.go @@ -211,6 +211,16 @@ func (h *operatorHandler) Post(w http.ResponseWriter, r *http.Request) { h.r.JSON(w, http.StatusInternalServerError, err.Error()) return } + case "scatter-region": + regionID, ok := input["region_id"].(float64) + if !ok { + h.r.JSON(w, http.StatusBadRequest, "missing region id") + return + } + if err := h.AddScatterRegionOperator(uint64(regionID)); err != nil { + h.r.JSON(w, http.StatusInternalServerError, err.Error()) + return + } default: h.r.JSON(w, http.StatusBadRequest, "unknown operator") return diff --git a/server/handler.go b/server/handler.go index 0003774c4b6..1f8623d8324 100644 --- a/server/handler.go +++ b/server/handler.go @@ -520,6 +520,25 @@ func (h *Handler) AddSplitRegionOperator(regionID uint64) error { return nil } +// AddScatterRegionOperator adds an operator to scatter a region. +func (h *Handler) AddScatterRegionOperator(regionID uint64) error { + c, err := h.getCoordinator() + if err != nil { + return errors.Trace(err) + } + + region := c.cluster.GetRegion(regionID) + if region == nil { + return ErrRegionNotFound(regionID) + } + + op := c.regionScatterer.Scatter(region) + if ok := c.addOperator(op); !ok { + return errors.Trace(errAddOperator) + } + return nil +} + // GetDownPeerRegions gets the region with down peer. func (h *Handler) GetDownPeerRegions() ([]*core.RegionInfo, error) { c := h.s.GetRaftCluster() diff --git a/server/schedule/region_scatterer.go b/server/schedule/region_scatterer.go index d2655cbbb97..b179b8fed85 100644 --- a/server/schedule/region_scatterer.go +++ b/server/schedule/region_scatterer.go @@ -100,6 +100,7 @@ func (r *RegionScatterer) scatterRegion(region *core.RegionInfo) *Operator { steps := make([]OperatorStep, 0, len(region.GetPeers())) stores := r.collectAvailableStores(region) + var kind OperatorKind for _, peer := range region.GetPeers() { if len(stores) == 0 { // Reset selected stores if we have no available stores. @@ -124,12 +125,13 @@ func (r *RegionScatterer) scatterRegion(region *core.RegionInfo) *Operator { peer.GetStoreId(), newPeer.GetStoreId(), newPeer.GetId()) steps = append(steps, op.steps...) steps = append(steps, TransferLeader{ToStore: newPeer.GetStoreId()}) + kind |= op.Kind() } if len(steps) == 0 { return nil } - return NewOperator("scatter-region", region.GetId(), OpAdmin, steps...) + return NewOperator("scatter-region", region.GetId(), kind, steps...) } func (r *RegionScatterer) selectPeerToReplace(stores map[uint64]*core.StoreInfo, region *core.RegionInfo, oldPeer *metapb.Peer) *metapb.Peer { From 3289a21cd649439a4964825f288294528b66449b Mon Sep 17 00:00:00 2001 From: disksing Date: Tue, 17 Apr 2018 09:48:00 +0800 Subject: [PATCH 2/2] *: fix panic. --- server/handler.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/handler.go b/server/handler.go index 1f8623d8324..2c2b47fd24b 100644 --- a/server/handler.go +++ b/server/handler.go @@ -533,6 +533,9 @@ func (h *Handler) AddScatterRegionOperator(regionID uint64) error { } op := c.regionScatterer.Scatter(region) + if op == nil { + return nil + } if ok := c.addOperator(op); !ok { return errors.Trace(errAddOperator) }