diff --git a/server/cluster/cluster_test.go b/server/cluster/cluster_test.go index a1be4c491cb..3728a7d6f72 100644 --- a/server/cluster/cluster_test.go +++ b/server/cluster/cluster_test.go @@ -373,7 +373,6 @@ func (s *testClusterInfoSuite) TestRegionFlowChanged(c *C) { newRegion = cluster.GetRegion(region.GetID()) c.Assert(region.GetBytesRead(), Equals, uint64(0)) c.Assert(newRegion.GetBytesRead(), Not(Equals), uint64(0)) - } func (s *testClusterInfoSuite) TestConcurrentRegionHeartbeat(c *C) { diff --git a/server/config/config.go b/server/config/config.go index 4e1ff831ce8..908648570e2 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -547,9 +547,8 @@ func (c *Config) adjustLog(meta *configMetaData) { // Clone returns a cloned configuration. func (c *Config) Clone() *Config { - cfg := &Config{} - *cfg = *c - return cfg + cfg := *c + return &cfg } func (c *Config) String() string { @@ -680,49 +679,19 @@ type ScheduleConfig struct { // Clone returns a cloned scheduling configuration. func (c *ScheduleConfig) Clone() *ScheduleConfig { - schedulers := make(SchedulerConfigs, len(c.Schedulers)) - copy(schedulers, c.Schedulers) - storeLimit := make(map[uint64]StoreLimitConfig, len(c.StoreLimit)) - for k, v := range c.StoreLimit { - storeLimit[k] = v - } - return &ScheduleConfig{ - MaxSnapshotCount: c.MaxSnapshotCount, - MaxPendingPeerCount: c.MaxPendingPeerCount, - MaxMergeRegionSize: c.MaxMergeRegionSize, - MaxMergeRegionKeys: c.MaxMergeRegionKeys, - SplitMergeInterval: c.SplitMergeInterval, - PatrolRegionInterval: c.PatrolRegionInterval, - MaxStoreDownTime: c.MaxStoreDownTime, - LeaderScheduleLimit: c.LeaderScheduleLimit, - LeaderSchedulePolicy: c.LeaderSchedulePolicy, - RegionScheduleLimit: c.RegionScheduleLimit, - ReplicaScheduleLimit: c.ReplicaScheduleLimit, - MergeScheduleLimit: c.MergeScheduleLimit, - EnableOneWayMerge: c.EnableOneWayMerge, - EnableCrossTableMerge: c.EnableCrossTableMerge, - HotRegionScheduleLimit: c.HotRegionScheduleLimit, - HotRegionCacheHitsThreshold: c.HotRegionCacheHitsThreshold, - StoreLimit: storeLimit, - TolerantSizeRatio: c.TolerantSizeRatio, - LowSpaceRatio: c.LowSpaceRatio, - HighSpaceRatio: c.HighSpaceRatio, - SchedulerMaxWaitingOperator: c.SchedulerMaxWaitingOperator, - DisableLearner: c.DisableLearner, - DisableRemoveDownReplica: c.DisableRemoveDownReplica, - DisableReplaceOfflineReplica: c.DisableReplaceOfflineReplica, - DisableMakeUpReplica: c.DisableMakeUpReplica, - DisableRemoveExtraReplica: c.DisableRemoveExtraReplica, - DisableLocationReplacement: c.DisableLocationReplacement, - EnableRemoveDownReplica: c.EnableRemoveDownReplica, - EnableReplaceOfflineReplica: c.EnableReplaceOfflineReplica, - EnableMakeUpReplica: c.EnableMakeUpReplica, - EnableRemoveExtraReplica: c.EnableRemoveExtraReplica, - EnableLocationReplacement: c.EnableLocationReplacement, - EnableDebugMetrics: c.EnableDebugMetrics, - StoreLimitMode: c.StoreLimitMode, - Schedulers: schedulers, + schedulers := append(c.Schedulers[:0:0], c.Schedulers...) + var storeLimit map[uint64]StoreLimitConfig + if c.StoreLimit != nil { + storeLimit = make(map[uint64]StoreLimitConfig, len(c.StoreLimit)) + for k, v := range c.StoreLimit { + storeLimit[k] = v + } } + cfg := *c + cfg.StoreLimit = storeLimit + cfg.Schedulers = schedulers + cfg.SchedulersPayload = nil + return &cfg } const ( @@ -814,6 +783,10 @@ func (c *ScheduleConfig) adjust(meta *configMetaData) error { c.StoreBalanceRate = 0 } + if c.StoreLimit == nil { + c.StoreLimit = make(map[uint64]StoreLimitConfig) + } + return c.Validate() } @@ -963,15 +936,12 @@ type ReplicationConfig struct { EnablePlacementRules bool `toml:"enable-placement-rules" json:"enable-placement-rules,string"` } -func (c *ReplicationConfig) clone() *ReplicationConfig { - locationLabels := make(typeutil.StringSlice, len(c.LocationLabels)) - copy(locationLabels, c.LocationLabels) - return &ReplicationConfig{ - MaxReplicas: c.MaxReplicas, - LocationLabels: locationLabels, - StrictlyMatchLabel: c.StrictlyMatchLabel, - EnablePlacementRules: c.EnablePlacementRules, - } +// Clone makes a deep copy of the config. +func (c *ReplicationConfig) Clone() *ReplicationConfig { + locationLabels := append(c.LocationLabels[:0:0], c.LocationLabels...) + cfg := *c + cfg.LocationLabels = locationLabels + return &cfg } // Validate is used to validate if some replication configurations are right. @@ -1038,16 +1008,10 @@ func (c *PDServerConfig) adjust(meta *configMetaData) error { // Clone returns a cloned PD server config. func (c *PDServerConfig) Clone() *PDServerConfig { - runtimeServices := make(typeutil.StringSlice, len(c.RuntimeServices)) - copy(runtimeServices, c.RuntimeServices) - return &PDServerConfig{ - UseRegionStorage: c.UseRegionStorage, - MaxResetTSGap: c.MaxResetTSGap, - KeyType: c.KeyType, - MetricStorage: c.MetricStorage, - DashboardAddress: c.DashboardAddress, - RuntimeServices: runtimeServices, - } + runtimeServices := append(c.RuntimeServices[:0:0], c.RuntimeServices...) + cfg := *c + cfg.RuntimeServices = runtimeServices + return &cfg } // Validate is used to validate if some pd-server configurations are right. diff --git a/server/config/config_test.go b/server/config/config_test.go index ad2dccf2476..07d1b814cb5 100644 --- a/server/config/config_test.go +++ b/server/config/config_test.go @@ -399,3 +399,27 @@ wait-store-timeout = "120s" c.Assert(err, IsNil) c.Assert(cfg.ReplicationMode.ReplicationMode, Equals, "majority") } + +func (s *testConfigSuite) TestConfigClone(c *C) { + cfg := &Config{} + cfg.Adjust(nil) + c.Assert(cfg.Clone(), DeepEquals, cfg) + + emptyConfigMetaData := newConfigMetadata(nil) + + schedule := &ScheduleConfig{} + schedule.adjust(emptyConfigMetaData) + c.Assert(schedule.Clone(), DeepEquals, schedule) + + replication := &ReplicationConfig{} + replication.adjust(emptyConfigMetaData) + c.Assert(replication.Clone(), DeepEquals, replication) + + pdServer := &PDServerConfig{} + pdServer.adjust(emptyConfigMetaData) + c.Assert(pdServer.Clone(), DeepEquals, pdServer) + + replicationMode := &ReplicationModeConfig{} + replicationMode.adjust(emptyConfigMetaData) + c.Assert(replicationMode.Clone(), DeepEquals, replicationMode) +} diff --git a/server/config/persist_options.go b/server/config/persist_options.go index 8f6e2210ecf..bcd33306fa1 100644 --- a/server/config/persist_options.go +++ b/server/config/persist_options.go @@ -137,7 +137,7 @@ func (o *PersistOptions) IsPlacementRulesEnabled() bool { // SetPlacementRuleEnabled set PlacementRuleEnabled func (o *PersistOptions) SetPlacementRuleEnabled(enabled bool) { - v := o.GetReplicationConfig().clone() + v := o.GetReplicationConfig().Clone() v.EnablePlacementRules = enabled o.SetReplicationConfig(v) } @@ -154,7 +154,7 @@ func (o *PersistOptions) GetMaxReplicas() int { // SetMaxReplicas sets the number of replicas for each region. func (o *PersistOptions) SetMaxReplicas(replicas int) { - v := o.GetReplicationConfig().clone() + v := o.GetReplicationConfig().Clone() v.MaxReplicas = uint64(replicas) o.SetReplicationConfig(v) } diff --git a/server/server.go b/server/server.go index be7f0e08e1e..5f5284e2a08 100644 --- a/server/server.go +++ b/server/server.go @@ -714,9 +714,9 @@ func (s *Server) StartTimestamp() int64 { // GetConfig gets the config information. func (s *Server) GetConfig() *config.Config { cfg := s.cfg.Clone() - cfg.Schedule = *s.persistOptions.GetScheduleConfig() - cfg.Replication = *s.persistOptions.GetReplicationConfig() - cfg.PDServerCfg = *s.persistOptions.GetPDServerConfig() + cfg.Schedule = *s.persistOptions.GetScheduleConfig().Clone() + cfg.Replication = *s.persistOptions.GetReplicationConfig().Clone() + cfg.PDServerCfg = *s.persistOptions.GetPDServerConfig().Clone() cfg.ReplicationMode = *s.persistOptions.GetReplicationModeConfig() cfg.LabelProperty = s.persistOptions.GetLabelPropertyConfig().Clone() cfg.ClusterVersion = *s.persistOptions.GetClusterVersion()