diff --git a/pkg/mcs/scheduling/server/cluster.go b/pkg/mcs/scheduling/server/cluster.go index a5a3a709184..c9f50632a2c 100644 --- a/pkg/mcs/scheduling/server/cluster.go +++ b/pkg/mcs/scheduling/server/cluster.go @@ -28,7 +28,6 @@ import ( "github.com/tikv/pd/pkg/schedule/schedulers" "github.com/tikv/pd/pkg/schedule/splitter" types "github.com/tikv/pd/pkg/schedule/type" - "github.com/tikv/pd/pkg/slice" "github.com/tikv/pd/pkg/statistics" "github.com/tikv/pd/pkg/statistics/buckets" "github.com/tikv/pd/pkg/statistics/utils" @@ -62,6 +61,27 @@ type Cluster struct { miscRunner ratelimit.Runner // logRunner is used to process the log asynchronously. logRunner ratelimit.Runner + + schedulerNotifier schedulerNotifier +} + +type schedulerNotifier struct { + addNotifier chan string + removeNotifier chan string +} + +func (s *schedulerNotifier) addScheduler(name string) { + select { + case s.addNotifier <- name: + default: + } +} + +func (s *schedulerNotifier) removeScheduler(name string) { + select { + case s.removeNotifier <- name: + default: + } } const ( @@ -258,9 +278,10 @@ func (c *Cluster) SwitchAPIServerLeader(new pdpb.PDClient) bool { return c.apiServerLeader.CompareAndSwap(old, new) } -func trySend(notifier chan struct{}) { +// trySend try to send all default schedulers. +func trySend(notifier chan string) { select { - case notifier <- struct{}{}: + case notifier <- "": // If the channel is not empty, it means the check is triggered. default: } @@ -271,86 +292,104 @@ func (c *Cluster) updateScheduler() { defer logutil.LogPanic() defer c.wg.Done() + var ( + schedulerName string + addNotifier = make(chan string, 1) + removeNotifier = make(chan string, 1) + ) + c.schedulerNotifier = schedulerNotifier{ + addNotifier: addNotifier, + removeNotifier: removeNotifier, + } // Make sure the coordinator has initialized all the existing schedulers. c.waitSchedulersInitialized() - // Establish a notifier to listen the schedulers updating. - notifier := make(chan struct{}, 1) + // Make sure the check will be triggered once later. trySend(notifier) - c.persistConfig.SetSchedulersUpdatingNotifier(notifier) + ticker := time.NewTicker(time.Second) defer ticker.Stop() +loop: for { + retryOnNotRunning := func() { + if !c.running.Load() { + select { + case <-c.ctx.Done(): + log.Info("cluster is closing, stop listening the schedulers updating notifier") + return + case <-ticker.C: + // retry + trySend(notifier) + continue loop + } + } + } select { case <-c.ctx.Done(): log.Info("cluster is closing, stop listening the schedulers updating notifier") return - case <-notifier: + case schedulerName = <-addNotifier: + retryOnNotRunning() // This is triggered by the watcher when the schedulers are updated. - } - - if !c.running.Load() { - select { - case <-c.ctx.Done(): - log.Info("cluster is closing, stop listening the schedulers updating notifier") - return - case <-ticker.C: - // retry - trySend(notifier) - continue - } + case schedulerName = <-removeNotifier: } log.Info("schedulers updating notifier is triggered, try to update the scheduler") + type schedulerConfig struct { + Args []string `json:"args"` + Disable bool `json:"disable"` + } var ( - schedulersController = c.coordinator.GetSchedulersController() - latestSchedulersConfig = c.persistConfig.GetScheduleConfig().Schedulers + schedulersController = c.coordinator.GetSchedulersController() ) + // Create the newly added schedulers. - for _, scheduler := range latestSchedulersConfig { - schedulerType := types.ConvertOldStrToType[scheduler.Type] - s, err := schedulers.CreateScheduler( - schedulerType, - c.coordinator.GetOperatorController(), - c.storage, - schedulers.ConfigSliceDecoder(schedulerType, scheduler.Args), - schedulersController.RemoveScheduler, - ) - if err != nil { - log.Error("failed to create scheduler", - zap.String("scheduler-type", scheduler.Type), - zap.Strings("scheduler-args", scheduler.Args), - errs.ZapError(err)) - continue - } - name := s.GetName() - if existed, _ := schedulersController.IsSchedulerExisted(name); existed { - log.Info("scheduler has already existed, skip adding it", - zap.String("scheduler-name", name), - zap.Strings("scheduler-args", scheduler.Args)) - continue - } - if err := schedulersController.AddScheduler(s, scheduler.Args...); err != nil { - log.Error("failed to add scheduler", - zap.String("scheduler-name", name), - zap.Strings("scheduler-args", scheduler.Args), - errs.ZapError(err)) - continue - } - log.Info("add scheduler successfully", + schedulerType := types.ConvertOldStrToType[schedulerName] + cfg, err := c.storage.LoadSchedulerConfig(schedulerName) + if err != nil { + log.Error("failed to load scheduler config", + zap.String("scheduler-name", schedulerName), + errs.ZapError(err)) + continue + } + + s, err := schedulers.CreateScheduler( + schedulerType, + c.coordinator.GetOperatorController(), + c.storage, + schedulers.ConfigJSONDecoder([]byte(cfg)), + schedulersController.RemoveScheduler, + ) + if err != nil { + log.Error("failed to create scheduler", + zap.Stringer("scheduler-type", schedulerType), + zap.String("scheduler-cfg", cfg), + errs.ZapError(err)) + continue + } + name := s.GetName() + if existed, _ := schedulersController.IsSchedulerExisted(name); existed { + log.Info("scheduler has already existed, skip adding it", + zap.String("scheduler-name", name), + zap.String("scheduler-cfg", cfg)) + continue + } + if err := schedulersController.AddScheduler(s); err != nil { + log.Error("failed to add scheduler", zap.String("scheduler-name", name), - zap.Strings("scheduler-args", scheduler.Args)) + zap.String("scheduler-cfg", cfg), + errs.ZapError(err)) + continue } + log.Info("add scheduler successfully", + zap.String("scheduler-name", name), + zap.String("scheduler-cfg", cfg)) + // Remove the deleted schedulers. for _, name := range schedulersController.GetSchedulerNames() { scheduler := schedulersController.GetScheduler(name) oldType := types.SchedulerTypeCompatibleMap[scheduler.GetType()] - if slice.AnyOf(latestSchedulersConfig, func(i int) bool { - return latestSchedulersConfig[i].Type == oldType - }) { - continue - } if err := schedulersController.RemoveScheduler(name); err != nil { log.Error("failed to remove scheduler", zap.String("scheduler-name", name), diff --git a/pkg/mcs/scheduling/server/config/config.go b/pkg/mcs/scheduling/server/config/config.go index 4b855d09899..fc20fcfe261 100644 --- a/pkg/mcs/scheduling/server/config/config.go +++ b/pkg/mcs/scheduling/server/config/config.go @@ -18,7 +18,6 @@ import ( "fmt" "os" "path/filepath" - "reflect" "strconv" "strings" "sync/atomic" @@ -230,9 +229,6 @@ type PersistConfig struct { schedule atomic.Value replication atomic.Value storeConfig atomic.Value - // schedulersUpdatingNotifier is used to notify that the schedulers have been updated. - // Store as `chan<- struct{}`. - schedulersUpdatingNotifier atomic.Value } // NewPersistConfig creates a new PersistConfig instance. @@ -248,27 +244,6 @@ func NewPersistConfig(cfg *Config, ttl *cache.TTLString) *PersistConfig { return o } -// SetSchedulersUpdatingNotifier sets the schedulers updating notifier. -func (o *PersistConfig) SetSchedulersUpdatingNotifier(notifier chan<- struct{}) { - o.schedulersUpdatingNotifier.Store(notifier) -} - -func (o *PersistConfig) getSchedulersUpdatingNotifier() chan<- struct{} { - v := o.schedulersUpdatingNotifier.Load() - if v == nil { - return nil - } - return v.(chan<- struct{}) -} - -func (o *PersistConfig) tryNotifySchedulersUpdating() { - notifier := o.getSchedulersUpdatingNotifier() - if notifier == nil { - return - } - notifier <- struct{}{} -} - // GetClusterVersion returns the cluster version. func (o *PersistConfig) GetClusterVersion() *semver.Version { return (*semver.Version)(atomic.LoadPointer(&o.clusterVersion)) @@ -286,25 +261,7 @@ func (o *PersistConfig) GetScheduleConfig() *sc.ScheduleConfig { // SetScheduleConfig sets the scheduling configuration dynamically. func (o *PersistConfig) SetScheduleConfig(cfg *sc.ScheduleConfig) { - old := o.GetScheduleConfig() o.schedule.Store(cfg) - // The coordinator is not aware of the underlying scheduler config changes, - // we should notify it to update the schedulers proactively. - if !reflect.DeepEqual(old.Schedulers, cfg.Schedulers) { - o.tryNotifySchedulersUpdating() - } -} - -// AdjustScheduleCfg adjusts the schedule config during the initialization. -func AdjustScheduleCfg(scheduleCfg *sc.ScheduleConfig) { - // In case we add new default schedulers. - for _, ps := range sc.DefaultSchedulers { - if slice.NoneOf(scheduleCfg.Schedulers, func(i int) bool { - return scheduleCfg.Schedulers[i].Type == ps.Type - }) { - scheduleCfg.Schedulers = append(scheduleCfg.Schedulers, ps) - } - } } // GetReplicationConfig returns replication configurations. @@ -647,18 +604,6 @@ func (o *PersistConfig) SetMaxReplicas(replicas int) { o.SetReplicationConfig(v) } -// IsSchedulerDisabled returns if the scheduler is disabled. -func (o *PersistConfig) IsSchedulerDisabled(tp types.CheckerSchedulerType) bool { - oldType := types.SchedulerTypeCompatibleMap[tp] - schedulers := o.GetScheduleConfig().Schedulers - for _, s := range schedulers { - if oldType == s.Type { - return s.Disable - } - } - return false -} - // SetPlacementRulesCacheEnabled sets if the placement rules cache is enabled. func (o *PersistConfig) SetPlacementRulesCacheEnabled(enabled bool) { v := o.GetReplicationConfig().Clone() diff --git a/pkg/mcs/scheduling/server/config/watcher.go b/pkg/mcs/scheduling/server/config/watcher.go index d1ca99bd36d..28889962214 100644 --- a/pkg/mcs/scheduling/server/config/watcher.go +++ b/pkg/mcs/scheduling/server/config/watcher.go @@ -60,6 +60,7 @@ type Watcher struct { *PersistConfig // Some data, like the scheduler configs, should be loaded into the storage // to make sure the coordinator could access them correctly. + // It is a memory storage. storage storage.Storage // schedulersController is used to trigger the scheduler's config reloading. // Store as `*schedulers.Controller`. @@ -129,7 +130,6 @@ func (cw *Watcher) initializeConfigWatcher() error { return err } log.Info("update scheduling config", zap.Reflect("new", cfg)) - AdjustScheduleCfg(&cfg.Schedule) cw.SetClusterVersion(&cfg.ClusterVersion) cw.SetScheduleConfig(&cfg.Schedule) cw.SetReplicationConfig(&cfg.Replication) diff --git a/pkg/schedule/config/config.go b/pkg/schedule/config/config.go index 124bff0a704..d526b2957eb 100644 --- a/pkg/schedule/config/config.go +++ b/pkg/schedule/config/config.go @@ -412,8 +412,6 @@ func (c *ScheduleConfig) Adjust(meta *configutil.ConfigMetaData, reloading bool) c.HaltScheduling = defaultHaltScheduling } - adjustSchedulers(&c.Schedulers, DefaultSchedulers) - for k, b := range c.migrateConfigurationMap() { v, err := parseDeprecatedFlag(meta, k, *b[0], *b[1]) if err != nil { @@ -574,16 +572,6 @@ var DefaultSchedulers = SchedulerConfigs{ {Type: types.SchedulerTypeCompatibleMap[types.EvictSlowStoreScheduler]}, } -// IsDefaultScheduler checks whether the scheduler is enabled by default. -func IsDefaultScheduler(typ string) bool { - for _, c := range DefaultSchedulers { - if typ == c.Type { - return true - } - } - return false -} - // ReplicationConfig is the replication configuration. // NOTE: This type is exported by HTTP API. Please pay more attention when modifying it. type ReplicationConfig struct { diff --git a/pkg/schedule/config/config_provider.go b/pkg/schedule/config/config_provider.go index d7bc38a7c03..3b57621f32a 100644 --- a/pkg/schedule/config/config_provider.go +++ b/pkg/schedule/config/config_provider.go @@ -50,9 +50,6 @@ type SchedulerConfigProvider interface { SetSchedulingAllowanceStatus(bool, string) GetStoresLimit() map[uint64]StoreLimitConfig - IsSchedulerDisabled(types.CheckerSchedulerType) bool - AddSchedulerCfg(types.CheckerSchedulerType, []string) - RemoveSchedulerCfg(types.CheckerSchedulerType) Persist(endpoint.ConfigStorage) error GetRegionScheduleLimit() uint64 diff --git a/pkg/schedule/coordinator.go b/pkg/schedule/coordinator.go index 89c99ac90b8..38de2fe34b6 100644 --- a/pkg/schedule/coordinator.go +++ b/pkg/schedule/coordinator.go @@ -20,13 +20,11 @@ import ( "sync" "time" - "github.com/pingcap/errors" "github.com/pingcap/failpoint" "github.com/pingcap/log" "github.com/tikv/pd/pkg/core" "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/pkg/schedule/checker" - sc "github.com/tikv/pd/pkg/schedule/config" sche "github.com/tikv/pd/pkg/schedule/core" "github.com/tikv/pd/pkg/schedule/diagnostic" "github.com/tikv/pd/pkg/schedule/hbstream" @@ -194,7 +192,7 @@ func (c *Coordinator) driveSlowNodeScheduler() { s, err := schedulers.CreateScheduler(typ, c.opController, c.cluster.GetStorage(), schedulers.ConfigSliceDecoder(typ, args), c.schedulers.RemoveScheduler) if err != nil { log.Warn("initializing evict-slow-trend scheduler failed", errs.ZapError(err)) - } else if err = c.schedulers.AddScheduler(s, args...); err != nil { + } else if err = c.schedulers.AddScheduler(s); err != nil { log.Error("can not add scheduler", zap.String("scheduler-name", s.GetName()), zap.Strings("scheduler-args", args), errs.ZapError(err)) } } @@ -269,97 +267,30 @@ func (c *Coordinator) InitSchedulers(needRun bool) { if err != nil { log.Fatal("cannot load schedulers' config", errs.ZapError(err)) } - scheduleCfg := c.cluster.GetSchedulerConfig().GetScheduleConfig().Clone() - // The new way to create scheduler with the independent configuration. + for i, name := range scheduleNames { data := configs[i] typ := schedulers.FindSchedulerTypeByName(name) - var cfg sc.SchedulerConfig - for _, c := range scheduleCfg.Schedulers { - if c.Type == types.SchedulerTypeCompatibleMap[typ] { - cfg = c - break - } - } - if len(cfg.Type) == 0 { - log.Error("the scheduler type not found", zap.String("scheduler-name", name), errs.ZapError(errs.ErrSchedulerNotFound)) - continue - } - if cfg.Disable { - log.Info("skip create scheduler with independent configuration", zap.String("scheduler-name", name), zap.String("scheduler-type", cfg.Type), zap.Strings("scheduler-args", cfg.Args)) - continue - } - s, err := schedulers.CreateScheduler(types.ConvertOldStrToType[cfg.Type], c.opController, - c.cluster.GetStorage(), schedulers.ConfigJSONDecoder([]byte(data)), c.schedulers.RemoveScheduler) + + s, err := schedulers.CreateScheduler(typ, c.opController, c.cluster.GetStorage(), + schedulers.ConfigJSONDecoder([]byte(data)), c.schedulers.RemoveScheduler) if err != nil { - log.Error("can not create scheduler with independent configuration", zap.String("scheduler-name", name), zap.Strings("scheduler-args", cfg.Args), errs.ZapError(err)) + log.Error("can not create scheduler", zap.String("scheduler-name", name), errs.ZapError(err)) continue } if needRun { - log.Info("create scheduler with independent configuration", zap.String("scheduler-name", s.GetName())) if err = c.schedulers.AddScheduler(s); err != nil { - log.Error("can not add scheduler with independent configuration", - zap.String("scheduler-name", s.GetName()), zap.Strings("scheduler-args", cfg.Args), errs.ZapError(err)) + log.Error("can not add scheduler", + zap.String("scheduler-name", s.GetName()), errs.ZapError(err)) } } else { - log.Info("create scheduler handler with independent configuration", zap.String("scheduler-name", s.GetName())) if err = c.schedulers.AddSchedulerHandler(s); err != nil { - log.Error("can not add scheduler handler with independent configuration", - zap.String("scheduler-name", s.GetName()), zap.Strings("scheduler-args", cfg.Args), errs.ZapError(err)) - } - } - } - - // The old way to create the scheduler. - k := 0 - for _, schedulerCfg := range scheduleCfg.Schedulers { - if schedulerCfg.Disable { - scheduleCfg.Schedulers[k] = schedulerCfg - k++ - log.Info("skip create scheduler", zap.String("scheduler-type", schedulerCfg.Type), zap.Strings("scheduler-args", schedulerCfg.Args)) - continue - } - - tp := types.ConvertOldStrToType[schedulerCfg.Type] - s, err := schedulers.CreateScheduler(tp, c.opController, - c.cluster.GetStorage(), schedulers.ConfigSliceDecoder(tp, schedulerCfg.Args), c.schedulers.RemoveScheduler) - if err != nil { - log.Error("can not create scheduler", zap.Stringer("type", tp), zap.String("scheduler-type", schedulerCfg.Type), - zap.Strings("scheduler-args", schedulerCfg.Args), errs.ZapError(err)) - continue - } - - if needRun { - log.Info("create scheduler", zap.String("scheduler-name", s.GetName()), - zap.Strings("scheduler-args", schedulerCfg.Args)) - if err = c.schedulers.AddScheduler(s, schedulerCfg.Args...); err != nil && - !errors.ErrorEqual(err, errs.ErrSchedulerExisted.FastGenByArgs()) { - log.Error("can not add scheduler", zap.String("scheduler-name", - s.GetName()), zap.Strings("scheduler-args", schedulerCfg.Args), errs.ZapError(err)) - } else { - // Only records the valid scheduler config. - scheduleCfg.Schedulers[k] = schedulerCfg - k++ - } - } else { - log.Info("create scheduler handler", zap.String("scheduler-name", s.GetName()), zap.Strings("scheduler-args", schedulerCfg.Args)) - if err = c.schedulers.AddSchedulerHandler(s, schedulerCfg.Args...); err != nil && !errors.ErrorEqual(err, errs.ErrSchedulerExisted.FastGenByArgs()) { - log.Error("can not add scheduler handler", zap.String("scheduler-name", s.GetName()), zap.Strings("scheduler-args", schedulerCfg.Args), errs.ZapError(err)) - } else { - scheduleCfg.Schedulers[k] = schedulerCfg - k++ + log.Error("can not add scheduler handler", + zap.String("scheduler-name", s.GetName()), errs.ZapError(err)) } } } - // Removes the invalid scheduler config and persist. - scheduleCfg.Schedulers = scheduleCfg.Schedulers[:k] - c.cluster.GetSchedulerConfig().SetScheduleConfig(scheduleCfg) - if err := c.cluster.GetSchedulerConfig().Persist(c.cluster.GetStorage()); err != nil { - log.Error("cannot persist schedule config", errs.ZapError(err)) - } - log.Info("scheduler config is updated", zap.Reflect("scheduler-config", scheduleCfg.Schedulers)) - c.markSchedulersInitialized() } diff --git a/pkg/schedule/diagnostic/diagnostic_manager.go b/pkg/schedule/diagnostic/diagnostic_manager.go index 5a56e849c3b..e150f74c1d3 100644 --- a/pkg/schedule/diagnostic/diagnostic_manager.go +++ b/pkg/schedule/diagnostic/diagnostic_manager.go @@ -48,8 +48,8 @@ func (d *Manager) GetDiagnosticResult(name string) (*schedulers.DiagnosticResult res := &schedulers.DiagnosticResult{Name: name, Timestamp: ts, Status: schedulers.Disabled} return res, nil } - isDisabled := d.config.IsSchedulerDisabled(scheduler.Scheduler.GetType()) - if isDisabled { + + if scheduler.Scheduler.IsDisable() { ts := uint64(time.Now().Unix()) res := &schedulers.DiagnosticResult{Name: name, Timestamp: ts, Status: schedulers.Disabled} return res, nil diff --git a/pkg/schedule/handler/handler.go b/pkg/schedule/handler/handler.go index 748a17b87ef..b5e8629dd01 100644 --- a/pkg/schedule/handler/handler.go +++ b/pkg/schedule/handler/handler.go @@ -855,11 +855,7 @@ func (h *Handler) GetSchedulerByStatus(status string, needTS bool) (any, error) case "disabled": disabledSchedulers := make([]string, 0, len(schedulers)) for _, scheduler := range schedulers { - disabled, err := sc.IsSchedulerDisabled(scheduler) - if err != nil { - return nil, err - } - if disabled { + if sc.GetScheduler(scheduler).IsDisable() { disabledSchedulers = append(disabledSchedulers, scheduler) } } @@ -870,11 +866,7 @@ func (h *Handler) GetSchedulerByStatus(status string, needTS bool) (any, error) // We should not return the disabled schedulers here. enabledSchedulers := make([]string, 0, len(schedulers)) for _, scheduler := range schedulers { - disabled, err := sc.IsSchedulerDisabled(scheduler) - if err != nil { - return nil, err - } - if !disabled { + if !sc.GetScheduler(scheduler).IsDisable() { enabledSchedulers = append(enabledSchedulers, scheduler) } } diff --git a/pkg/schedule/schedulers/balance_leader.go b/pkg/schedule/schedulers/balance_leader.go index ef254ee6950..fae497a0e81 100644 --- a/pkg/schedule/schedulers/balance_leader.go +++ b/pkg/schedule/schedulers/balance_leader.go @@ -55,7 +55,7 @@ const ( type balanceLeaderSchedulerConfig struct { syncutil.RWMutex - schedulerConfig + defaultSchedulerConfig Ranges []core.KeyRange `json:"ranges"` // Batch is used to generate multiple operators by one scheduling @@ -543,3 +543,18 @@ func (l *balanceLeaderScheduler) createOperator(solver *solver, collector *plan. op.SetAdditionalInfo("targetScore", strconv.FormatFloat(solver.targetScore, 'f', 2, 64)) return op } + +// IsDiable implements the Scheduler interface. +func (l *balanceLeaderScheduler) IsDisable() bool { + l.conf.RLock() + defer l.conf.RUnlock() + return l.conf.isDisable() +} + +// SetDiable implements the Scheduler interface. +func (l *balanceLeaderScheduler) SetDisable(disable bool) { + l.conf.RLock() + defer l.conf.RUnlock() + l.conf.setDisable(disable) + l.conf.save() +} diff --git a/pkg/schedule/schedulers/balance_region.go b/pkg/schedule/schedulers/balance_region.go index 174b6af1c83..57a653ac8f5 100644 --- a/pkg/schedule/schedulers/balance_region.go +++ b/pkg/schedule/schedulers/balance_region.go @@ -27,6 +27,7 @@ import ( "github.com/tikv/pd/pkg/schedule/operator" "github.com/tikv/pd/pkg/schedule/plan" types "github.com/tikv/pd/pkg/schedule/type" + "github.com/tikv/pd/pkg/utils/syncutil" "go.uber.org/zap" ) @@ -36,6 +37,9 @@ const ( ) type balanceRegionSchedulerConfig struct { + syncutil.RWMutex + defaultSchedulerConfig + Ranges []core.KeyRange `json:"ranges"` // TODO: When we prepare to use Ranges, we will need to implement the ReloadConfig function for this scheduler. } @@ -271,3 +275,18 @@ func (s *balanceRegionScheduler) transferPeer(solver *solver, collector *plan.Co } return nil } + +// IsDiable implements the Scheduler interface. +func (s *balanceRegionScheduler) IsDisable() bool { + s.conf.Lock() + defer s.conf.Unlock() + return s.conf.isDisable() +} + +// SetDiable implements the Scheduler interface. +func (s *balanceRegionScheduler) SetDisable(disable bool) { + s.conf.Lock() + defer s.conf.Unlock() + s.conf.setDisable(disable) + s.conf.save() +} diff --git a/pkg/schedule/schedulers/base_scheduler.go b/pkg/schedule/schedulers/base_scheduler.go index b3dae9856e6..a1659170aca 100644 --- a/pkg/schedule/schedulers/base_scheduler.go +++ b/pkg/schedule/schedulers/base_scheduler.go @@ -114,3 +114,9 @@ func (s *BaseScheduler) GetName() string { func (s *BaseScheduler) GetType() types.CheckerSchedulerType { return s.tp } + +// IsDiable implements the Scheduler interface. +func (*BaseScheduler) IsDisable() bool { return false } + +// SetDisable implements the Scheduler interface. +func (*BaseScheduler) SetDisable(bool) {} diff --git a/pkg/schedule/schedulers/config.go b/pkg/schedule/schedulers/config.go index 0c7caf686c3..2a12b7d0ed7 100644 --- a/pkg/schedule/schedulers/config.go +++ b/pkg/schedule/schedulers/config.go @@ -21,15 +21,19 @@ import ( ) type schedulerConfig interface { + init(name string, storage endpoint.ConfigStorage, data any) save() error load(any) error - init(name string, storage endpoint.ConfigStorage, data any) + setArgs([]string) + getArgs() []string } type baseSchedulerConfig struct { name string storage endpoint.ConfigStorage + // Args is the input arguments of the scheduler. + Args []string `json:"args"` // data is the config of the scheduler. data any } @@ -58,3 +62,38 @@ func (b *baseSchedulerConfig) load(v any) error { } return DecodeConfig([]byte(data), v) } + +func (b *baseSchedulerConfig) setArgs(args []string) { + b.Args = args +} + +func (b *baseSchedulerConfig) getArgs() []string { + return b.Args +} + +type defaultSchedulerConfig interface { + schedulerConfig + + isDisable() bool + setDisable(bool) +} + +type baseDefaultSchedulerConfig struct { + schedulerConfig + + Disabled bool `json:"disabled"` +} + +func newBaseDefaultSchedulerConfig() *baseDefaultSchedulerConfig { + return &baseDefaultSchedulerConfig{ + schedulerConfig: &baseSchedulerConfig{}, + } +} + +func (b *baseDefaultSchedulerConfig) isDisable() bool { + return b.Disabled +} + +func (b *baseDefaultSchedulerConfig) setDisable(disabled bool) { + b.Disabled = disabled +} diff --git a/pkg/schedule/schedulers/evict_slow_store.go b/pkg/schedule/schedulers/evict_slow_store.go index de581f597bb..27d9bb35442 100644 --- a/pkg/schedule/schedulers/evict_slow_store.go +++ b/pkg/schedule/schedulers/evict_slow_store.go @@ -43,7 +43,7 @@ const ( type evictSlowStoreSchedulerConfig struct { syncutil.RWMutex - schedulerConfig + defaultSchedulerConfig cluster *core.BasicCluster // Last timestamp of the chosen slow store for eviction. @@ -55,7 +55,7 @@ type evictSlowStoreSchedulerConfig struct { func initEvictSlowStoreSchedulerConfig() *evictSlowStoreSchedulerConfig { return &evictSlowStoreSchedulerConfig{ - schedulerConfig: &baseSchedulerConfig{}, + defaultSchedulerConfig: newBaseDefaultSchedulerConfig(), lastSlowStoreCaptureTS: time.Time{}, RecoveryDurationGap: defaultRecoveryDurationGap, EvictedStores: make([]uint64, 0), @@ -313,6 +313,21 @@ func (s *evictSlowStoreScheduler) Schedule(cluster sche.SchedulerCluster, _ bool return s.schedulerEvictLeader(cluster), nil } +// IsDiable implements the Scheduler interface. +func (s *evictSlowStoreScheduler) IsDisable() bool { + s.conf.Lock() + defer s.conf.Unlock() + return s.conf.isDisable() +} + +// SetDisable implements the Scheduler interface. +func (s *evictSlowStoreScheduler) SetDisable(disable bool) { + s.conf.Lock() + defer s.conf.Unlock() + s.conf.setDisable(disable) + s.conf.save() +} + // newEvictSlowStoreScheduler creates a scheduler that detects and evicts slow stores. func newEvictSlowStoreScheduler(opController *operator.Controller, conf *evictSlowStoreSchedulerConfig) Scheduler { handler := newEvictSlowStoreHandler(conf) diff --git a/pkg/schedule/schedulers/hot_region.go b/pkg/schedule/schedulers/hot_region.go index ab595ec9058..c0e63193349 100644 --- a/pkg/schedule/schedulers/hot_region.go +++ b/pkg/schedule/schedulers/hot_region.go @@ -284,6 +284,19 @@ func (h *hotScheduler) Schedule(cluster sche.SchedulerCluster, _ bool) ([]*opera return h.dispatch(typ, cluster), nil } +// IsDisable implements the Scheduler interface. +func (h *hotScheduler) IsDisable() bool { + return h.conf.isDisable() +} + +// SetDisable implements the Scheduler interface. +func (h *hotScheduler) SetDisable(disable bool) { + h.Lock() + defer h.Unlock() + h.conf.setDisable(disable) + h.conf.save() +} + func (h *hotScheduler) dispatch(typ resourceType, cluster sche.SchedulerCluster) []*operator.Operator { h.Lock() defer h.Unlock() diff --git a/pkg/schedule/schedulers/hot_region_config.go b/pkg/schedule/schedulers/hot_region_config.go index 0424a582bf4..af6a4603fb7 100644 --- a/pkg/schedule/schedulers/hot_region_config.go +++ b/pkg/schedule/schedulers/hot_region_config.go @@ -58,7 +58,7 @@ var compatiblePrioritiesConfig = prioritiesConfig{ // params about hot region. func initHotRegionScheduleConfig() *hotRegionSchedulerConfig { cfg := &hotRegionSchedulerConfig{ - schedulerConfig: &baseSchedulerConfig{}, + defaultSchedulerConfig: newBaseDefaultSchedulerConfig(), MinHotByteRate: 100, MinHotKeyRate: 10, MinHotQueryRate: 10, @@ -114,7 +114,7 @@ func (conf *hotRegionSchedulerConfig) getValidConf() *hotRegionSchedulerConfig { type hotRegionSchedulerConfig struct { syncutil.RWMutex - schedulerConfig + defaultSchedulerConfig lastQuerySupported bool diff --git a/pkg/schedule/schedulers/init.go b/pkg/schedule/schedulers/init.go index 16f78284cf8..0f1679883c7 100644 --- a/pkg/schedule/schedulers/init.go +++ b/pkg/schedule/schedulers/init.go @@ -49,6 +49,7 @@ func schedulersRegister() { } conf.Ranges = ranges conf.Batch = BalanceLeaderBatchSize + conf.setArgs(args) return nil } }) @@ -56,7 +57,7 @@ func schedulersRegister() { RegisterScheduler(types.BalanceLeaderScheduler, func(opController *operator.Controller, storage endpoint.ConfigStorage, decoder ConfigDecoder, _ ...func(string) error) (Scheduler, error) { conf := &balanceLeaderSchedulerConfig{ - schedulerConfig: &baseSchedulerConfig{}, + defaultSchedulerConfig: newBaseDefaultSchedulerConfig(), } if err := decoder(conf); err != nil { return nil, err @@ -81,17 +82,22 @@ func schedulersRegister() { return err } conf.Ranges = ranges + conf.setArgs(args) return nil } }) RegisterScheduler(types.BalanceRegionScheduler, func(opController *operator.Controller, - _ endpoint.ConfigStorage, decoder ConfigDecoder, _ ...func(string) error) (Scheduler, error) { - conf := &balanceRegionSchedulerConfig{} + storage endpoint.ConfigStorage, decoder ConfigDecoder, _ ...func(string) error) (Scheduler, error) { + conf := &balanceRegionSchedulerConfig{ + defaultSchedulerConfig: newBaseDefaultSchedulerConfig(), + } if err := decoder(conf); err != nil { return nil, err } - return newBalanceRegionScheduler(opController, conf), nil + sche := newBalanceRegionScheduler(opController, conf) + conf.init(sche.GetName(), storage, conf) + return sche, nil }) // balance witness @@ -107,6 +113,7 @@ func schedulersRegister() { } conf.Ranges = ranges conf.Batch = balanceWitnessBatchSize + conf.setArgs(args) return nil } }) @@ -149,6 +156,7 @@ func schedulersRegister() { } conf.StoreIDWithRanges[id] = ranges conf.Batch = EvictLeaderBatchSize + conf.setArgs(args) return nil } }) @@ -215,6 +223,7 @@ func schedulersRegister() { if !conf.setStore(leaderID, storeIDs) { return errs.ErrSchedulerConfig } + conf.setArgs(args) return nil } }) @@ -284,6 +293,7 @@ func schedulersRegister() { return err } conf.StoreIDWithRanges[id] = ranges + conf.setArgs(args) return nil } }) @@ -316,17 +326,22 @@ func schedulersRegister() { return err } conf.Ranges = ranges + conf.setArgs(args) return nil } }) RegisterScheduler(types.LabelScheduler, func(opController *operator.Controller, - _ endpoint.ConfigStorage, decoder ConfigDecoder, _ ...func(string) error) (Scheduler, error) { - conf := &labelSchedulerConfig{} + storage endpoint.ConfigStorage, decoder ConfigDecoder, _ ...func(string) error) (Scheduler, error) { + conf := &labelSchedulerConfig{ + schedulerConfig: &baseSchedulerConfig{}, + } if err := decoder(conf); err != nil { return nil, err } - return newLabelScheduler(opController, conf), nil + sche := newLabelScheduler(opController, conf) + conf.init(sche.GetName(), storage, conf) + return sche, nil }) // random merge @@ -341,17 +356,22 @@ func schedulersRegister() { return err } conf.Ranges = ranges + conf.setArgs(args) return nil } }) RegisterScheduler(types.RandomMergeScheduler, func(opController *operator.Controller, - _ endpoint.ConfigStorage, decoder ConfigDecoder, _ ...func(string) error) (Scheduler, error) { - conf := &randomMergeSchedulerConfig{} + storage endpoint.ConfigStorage, decoder ConfigDecoder, _ ...func(string) error) (Scheduler, error) { + conf := &randomMergeSchedulerConfig{ + schedulerConfig: &baseSchedulerConfig{}, + } if err := decoder(conf); err != nil { return nil, err } - return newRandomMergeScheduler(opController, conf), nil + sche := newRandomMergeScheduler(opController, conf) + conf.init(sche.GetName(), storage, conf) + return sche, nil }) // scatter range @@ -371,6 +391,7 @@ func schedulersRegister() { conf.StartKey = args[0] conf.EndKey = args[1] conf.RangeName = args[2] + conf.setArgs(args) return nil } }) @@ -407,6 +428,7 @@ func schedulersRegister() { } conf.Limit = limit } + conf.setArgs(args) return nil } }) @@ -437,17 +459,22 @@ func schedulersRegister() { return err } conf.Ranges = ranges + conf.setArgs(args) return nil } }) RegisterScheduler(types.ShuffleLeaderScheduler, func(opController *operator.Controller, - _ endpoint.ConfigStorage, decoder ConfigDecoder, _ ...func(string) error) (Scheduler, error) { - conf := &shuffleLeaderSchedulerConfig{} + storage endpoint.ConfigStorage, decoder ConfigDecoder, _ ...func(string) error) (Scheduler, error) { + conf := &shuffleLeaderSchedulerConfig{ + schedulerConfig: &baseSchedulerConfig{}, + } if err := decoder(conf); err != nil { return nil, err } - return newShuffleLeaderScheduler(opController, conf), nil + sche := newShuffleLeaderScheduler(opController, conf) + conf.init(sche.GetName(), storage, conf) + return sche, nil }) // shuffle region @@ -463,6 +490,7 @@ func schedulersRegister() { } conf.Ranges = ranges conf.Roles = allRoles + conf.setArgs(args) return nil } }) diff --git a/pkg/schedule/schedulers/label.go b/pkg/schedule/schedulers/label.go index 8d4f42262ac..59304500635 100644 --- a/pkg/schedule/schedulers/label.go +++ b/pkg/schedule/schedulers/label.go @@ -34,6 +34,8 @@ const ( ) type labelSchedulerConfig struct { + schedulerConfig + Ranges []core.KeyRange `json:"ranges"` // TODO: When we prepare to use Ranges, we will need to implement the ReloadConfig function for this scheduler. } diff --git a/pkg/schedule/schedulers/random_merge.go b/pkg/schedule/schedulers/random_merge.go index 676e5407e72..d5ce8107eb0 100644 --- a/pkg/schedule/schedulers/random_merge.go +++ b/pkg/schedule/schedulers/random_merge.go @@ -35,6 +35,8 @@ const ( ) type randomMergeSchedulerConfig struct { + schedulerConfig + Ranges []core.KeyRange `json:"ranges"` // TODO: When we prepare to use Ranges, we will need to implement the ReloadConfig function for this scheduler. } diff --git a/pkg/schedule/schedulers/scheduler.go b/pkg/schedule/schedulers/scheduler.go index 7fce5d9c46e..721fabe8408 100644 --- a/pkg/schedule/schedulers/scheduler.go +++ b/pkg/schedule/schedulers/scheduler.go @@ -47,6 +47,14 @@ type Scheduler interface { CleanConfig(cluster sche.SchedulerCluster) Schedule(cluster sche.SchedulerCluster, dryRun bool) ([]*operator.Operator, []plan.Plan) IsScheduleAllowed(cluster sche.SchedulerCluster) bool + // IsDiable returns if the scheduler is disabled, it only works for default schedulers. + // - BalanceRegionScheduler + // - BalanceLeaderScheduler + // - BalanceHotRegionScheduler + // - EvictSlowStoreScheduler + IsDisable() bool + // SetDisable sets the scheduler's disable, it only works for default schedulers. + SetDisable(bool) } // EncodeConfig encode the custom config for each scheduler. diff --git a/pkg/schedule/schedulers/scheduler_controller.go b/pkg/schedule/schedulers/scheduler_controller.go index c29b75a371a..7df09cbb510 100644 --- a/pkg/schedule/schedulers/scheduler_controller.go +++ b/pkg/schedule/schedulers/scheduler_controller.go @@ -143,7 +143,7 @@ func (c *Controller) AddSchedulerHandler(scheduler Scheduler, args ...string) er defer c.Unlock() name := scheduler.GetName() - if _, ok := c.schedulerHandlers[name]; ok { + if _, ok := c.schedulerHandlers[name]; ok && !scheduler.IsDisable() { return errs.ErrSchedulerExisted.FastGenByArgs() } @@ -152,7 +152,6 @@ func (c *Controller) AddSchedulerHandler(scheduler Scheduler, args ...string) er log.Error("can not save HTTP scheduler config", zap.String("scheduler-name", scheduler.GetName()), errs.ZapError(err)) return err } - c.cluster.GetSchedulerConfig().AddSchedulerCfg(scheduler.GetType(), args) err := scheduler.PrepareConfig(c.cluster) return err } @@ -169,13 +168,6 @@ func (c *Controller) RemoveSchedulerHandler(name string) error { return errs.ErrSchedulerNotFound.FastGenByArgs() } - conf := c.cluster.GetSchedulerConfig() - conf.RemoveSchedulerCfg(s.(Scheduler).GetType()) - if err := conf.Persist(c.storage); err != nil { - log.Error("the option can not persist scheduler config", errs.ZapError(err)) - return err - } - if err := c.storage.RemoveSchedulerConfig(name); err != nil { log.Error("can not remove the scheduler config", errs.ZapError(err)) return err @@ -188,11 +180,11 @@ func (c *Controller) RemoveSchedulerHandler(name string) error { } // AddScheduler adds a scheduler. -func (c *Controller) AddScheduler(scheduler Scheduler, args ...string) error { +func (c *Controller) AddScheduler(scheduler Scheduler) error { c.Lock() defer c.Unlock() - if _, ok := c.schedulers[scheduler.GetName()]; ok { + if s, ok := c.schedulers[scheduler.GetName()]; ok && !s.IsDisable() { return errs.ErrSchedulerExisted.FastGenByArgs() } @@ -208,7 +200,6 @@ func (c *Controller) AddScheduler(scheduler Scheduler, args ...string) error { log.Error("can not save scheduler config", zap.String("scheduler-name", scheduler.GetName()), errs.ZapError(err)) return err } - c.cluster.GetSchedulerConfig().AddSchedulerCfg(s.Scheduler.GetType(), args) return nil } @@ -224,13 +215,6 @@ func (c *Controller) RemoveScheduler(name string) error { return errs.ErrSchedulerNotFound.FastGenByArgs() } - conf := c.cluster.GetSchedulerConfig() - conf.RemoveSchedulerCfg(s.Scheduler.GetType()) - if err := conf.Persist(c.storage); err != nil { - log.Error("the option can not persist scheduler config", errs.ZapError(err)) - return err - } - if err := c.storage.RemoveSchedulerConfig(name); err != nil { log.Error("can not remove the scheduler config", errs.ZapError(err)) return err @@ -321,7 +305,7 @@ func (c *Controller) IsSchedulerDisabled(name string) (bool, error) { if !ok { return false, errs.ErrSchedulerNotFound.FastGenByArgs() } - return c.cluster.GetSchedulerConfig().IsSchedulerDisabled(s.Scheduler.GetType()), nil + return s.IsDisable(), nil } // IsSchedulerExisted returns whether a scheduler is existed. diff --git a/pkg/schedule/schedulers/shuffle_leader.go b/pkg/schedule/schedulers/shuffle_leader.go index 4270613667b..bb554c57c3e 100644 --- a/pkg/schedule/schedulers/shuffle_leader.go +++ b/pkg/schedule/schedulers/shuffle_leader.go @@ -32,6 +32,8 @@ const ( ) type shuffleLeaderSchedulerConfig struct { + schedulerConfig + Ranges []core.KeyRange `json:"ranges"` // TODO: When we prepare to use Ranges, we will need to implement the ReloadConfig function for this scheduler. } diff --git a/pkg/schedule/type/type.go b/pkg/schedule/type/type.go index b7e0b26482e..39cee5b5fbf 100644 --- a/pkg/schedule/type/type.go +++ b/pkg/schedule/type/type.go @@ -145,3 +145,9 @@ var ( "label-scheduler": LabelScheduler, } ) + +// SchedulerNameToType converts the scheduler name to the CheckerSchedulerType. +func SchedulerNameToType(name string) CheckerSchedulerType { + // TODO: implement the special case for `scatter-range-scheduler` + return StringToSchedulerType[name] +} diff --git a/pkg/storage/kv/mem_kv.go b/pkg/storage/kv/mem_kv.go index b97a3d6cfa1..dc24ab3e0f6 100644 --- a/pkg/storage/kv/mem_kv.go +++ b/pkg/storage/kv/mem_kv.go @@ -28,7 +28,7 @@ type memoryKV struct { tree *btree.BTreeG[memoryKVItem] } -// NewMemoryKV returns an in-memory kvBase for testing. +// NewMemoryKV returns an in-memory kvBase. func NewMemoryKV() Base { return &memoryKV{ tree: btree.NewG(2, func(i, j memoryKVItem) bool { diff --git a/server/cluster/cluster_test.go b/server/cluster/cluster_test.go index 3f01305b3f1..3cc27ab438e 100644 --- a/server/cluster/cluster_test.go +++ b/server/cluster/cluster_test.go @@ -334,7 +334,7 @@ func addEvictLeaderScheduler(cluster *RaftCluster, storeID uint64) (evictSchedul if err != nil { return } - if err = cluster.AddScheduler(evictScheduler, args...); err != nil { + if err = cluster.AddScheduler(evictScheduler); err != nil { return } else if err = cluster.opt.Persist(cluster.GetStorage()); err != nil { return diff --git a/server/cluster/scheduling_controller.go b/server/cluster/scheduling_controller.go index b4c29ceed46..c17427b3901 100644 --- a/server/cluster/scheduling_controller.go +++ b/server/cluster/scheduling_controller.go @@ -376,10 +376,10 @@ func (sc *schedulingController) RemoveSchedulerHandler(name string) error { } // AddScheduler adds a scheduler. -func (sc *schedulingController) AddScheduler(scheduler schedulers.Scheduler, args ...string) error { +func (sc *schedulingController) AddScheduler(scheduler schedulers.Scheduler) error { sc.mu.RLock() defer sc.mu.RUnlock() - return sc.coordinator.GetSchedulersController().AddScheduler(scheduler, args...) + return sc.coordinator.GetSchedulersController().AddScheduler(scheduler) } // RemoveScheduler removes a scheduler. diff --git a/server/config/persist_options.go b/server/config/persist_options.go index b6963a6645a..020c643a287 100644 --- a/server/config/persist_options.go +++ b/server/config/persist_options.go @@ -17,7 +17,6 @@ package config import ( "context" "fmt" - "reflect" "strconv" "strings" "sync/atomic" @@ -33,8 +32,6 @@ import ( "github.com/tikv/pd/pkg/core/constant" "github.com/tikv/pd/pkg/core/storelimit" sc "github.com/tikv/pd/pkg/schedule/config" - types "github.com/tikv/pd/pkg/schedule/type" - "github.com/tikv/pd/pkg/slice" "github.com/tikv/pd/pkg/storage/endpoint" "github.com/tikv/pd/pkg/utils/etcdutil" "github.com/tikv/pd/pkg/utils/typeutil" @@ -669,18 +666,6 @@ func (o *PersistOptions) GetSchedulers() sc.SchedulerConfigs { return o.GetScheduleConfig().Schedulers } -// IsSchedulerDisabled returns if the scheduler is disabled. -func (o *PersistOptions) IsSchedulerDisabled(tp types.CheckerSchedulerType) bool { - oldType := types.SchedulerTypeCompatibleMap[tp] - schedulers := o.GetScheduleConfig().Schedulers - for _, s := range schedulers { - if oldType == s.Type { - return s.Disable - } - } - return false -} - // GetHotRegionsWriteInterval gets interval for PD to store Hot Region information. func (o *PersistOptions) GetHotRegionsWriteInterval() time.Duration { return o.GetScheduleConfig().HotRegionsWriteInterval.Duration @@ -691,47 +676,6 @@ func (o *PersistOptions) GetHotRegionsReservedDays() uint64 { return o.GetScheduleConfig().HotRegionsReservedDays } -// AddSchedulerCfg adds the scheduler configurations. -func (o *PersistOptions) AddSchedulerCfg(tp types.CheckerSchedulerType, args []string) { - oldType := types.SchedulerTypeCompatibleMap[tp] - v := o.GetScheduleConfig().Clone() - for i, schedulerCfg := range v.Schedulers { - // comparing args is to cover the case that there are schedulers in same type but not with same name - // such as two schedulers of type "evict-leader", - // one name is "evict-leader-scheduler-1" and the other is "evict-leader-scheduler-2" - if reflect.DeepEqual(schedulerCfg, sc.SchedulerConfig{Type: oldType, Args: args, Disable: false}) { - return - } - - if reflect.DeepEqual(schedulerCfg, sc.SchedulerConfig{Type: oldType, Args: args, Disable: true}) { - schedulerCfg.Disable = false - v.Schedulers[i] = schedulerCfg - o.SetScheduleConfig(v) - return - } - } - v.Schedulers = append(v.Schedulers, sc.SchedulerConfig{Type: oldType, Args: args, Disable: false}) - o.SetScheduleConfig(v) -} - -// RemoveSchedulerCfg removes the scheduler configurations. -func (o *PersistOptions) RemoveSchedulerCfg(tp types.CheckerSchedulerType) { - oldType := types.SchedulerTypeCompatibleMap[tp] - v := o.GetScheduleConfig().Clone() - for i, schedulerCfg := range v.Schedulers { - if oldType == schedulerCfg.Type { - if sc.IsDefaultScheduler(oldType) { - schedulerCfg.Disable = true - v.Schedulers[i] = schedulerCfg - } else { - v.Schedulers = append(v.Schedulers[:i], v.Schedulers[i+1:]...) - } - o.SetScheduleConfig(v) - return - } - } -} - // SetLabelProperty sets the label property. func (o *PersistOptions) SetLabelProperty(typ, labelKey, labelValue string) { cfg := o.GetLabelPropertyConfig().Clone() @@ -807,10 +751,10 @@ func (o *PersistOptions) Reload(storage endpoint.ConfigStorage) error { if err != nil { return err } - adjustScheduleCfg(&cfg.Schedule) // Some fields may not be stored in the storage, we need to calculate them manually. cfg.StoreConfig.Adjust() cfg.PDServerCfg.MigrateDeprecatedFlags() + cfg.Schedule.MigrateDeprecatedFlags() if isExist { o.schedule.Store(&cfg.Schedule) o.replication.Store(&cfg.Replication) @@ -825,18 +769,6 @@ func (o *PersistOptions) Reload(storage endpoint.ConfigStorage) error { return nil } -func adjustScheduleCfg(scheduleCfg *sc.ScheduleConfig) { - // In case we add new default schedulers. - for _, ps := range sc.DefaultSchedulers { - if slice.NoneOf(scheduleCfg.Schedulers, func(i int) bool { - return scheduleCfg.Schedulers[i].Type == ps.Type - }) { - scheduleCfg.Schedulers = append(scheduleCfg.Schedulers, ps) - } - } - scheduleCfg.MigrateDeprecatedFlags() -} - // CheckLabelProperty checks the label property. func (o *PersistOptions) CheckLabelProperty(typ string, labels []*metapb.StoreLabel) bool { pc := o.labelProperty.Load().(LabelPropertyConfig) diff --git a/server/handler.go b/server/handler.go index e3e4184f177..8e95a8d31eb 100644 --- a/server/handler.go +++ b/server/handler.go @@ -211,7 +211,7 @@ func (h *Handler) AddScheduler(tp types.CheckerSchedulerType, args ...string) er } log.Info("add scheduler handler successfully", zap.String("scheduler-name", s.GetName()), zap.Strings("scheduler-args", args)) } else { - if err = c.AddScheduler(s, args...); err != nil { + if err = c.AddScheduler(s); err != nil { log.Error("can not add scheduler", zap.String("scheduler-name", s.GetName()), zap.Strings("scheduler-args", args), errs.ZapError(err)) return err } diff --git a/tests/integrations/mcs/scheduling/server_test.go b/tests/integrations/mcs/scheduling/server_test.go index ab6bb93c60c..d44f684eb2c 100644 --- a/tests/integrations/mcs/scheduling/server_test.go +++ b/tests/integrations/mcs/scheduling/server_test.go @@ -375,9 +375,7 @@ func (suite *serverTestSuite) TestSchedulerSync() { checkDisabled := func(name string, shouldDisabled bool) { re.NotNil(schedulersController.GetScheduler(name), name) testutil.Eventually(re, func() bool { - disabled, err := schedulersController.IsSchedulerDisabled(name) - re.NoError(err, name) - return disabled == shouldDisabled + return schedulersController.GetScheduler(name).IsDisable() == shouldDisabled }) } for _, name := range defaultSchedulerNames {