func (m *ModeManager) UpdateConfig(config config.ReplicationModeConfig) error {
	m.Lock()
	defer m.Unlock()
	if m.config.ReplicationMode == modeMajority && config.ReplicationMode == modeDRAutoSync {
		old := m.config
		m.config = config
		err := m.drSwitchToSyncRecoverWithLock()
		if err != nil {
			m.config = old
		}
		return err
	}
	if m.config.ReplicationMode == modeDRAutoSync && config.ReplicationMode == modeDRAutoSync && m.config.DRAutoSync.LabelKey != config.DRAutoSync.LabelKey {
		old := m.config
		m.config = config
		err := m.drSwitchToAsyncWithLock()
		if err != nil {
			m.config = old
		}
		return err
	}
	m.config = config
	return nil
}
UpdateConfig updates configuration online and updates internal state.
package replication
import (
	"bytes"
	"context"
	"encoding/json"
	"strings"
	"sync"
	"time"
	pb "github.com/pingcap/kvproto/pkg/replication_modepb"
	"github.com/pingcap/log"
	"github.com/tikv/pd/pkg/errs"
	"github.com/tikv/pd/pkg/logutil"
	"github.com/tikv/pd/server/config"
	"github.com/tikv/pd/server/core"
	"github.com/tikv/pd/server/schedule/opt"
	"go.uber.org/zap"
)
const (
	modeMajority   = "majority"
	modeDRAutoSync = "dr-auto-sync"
)
func modeToPB(m string) pb.ReplicationMode {
	switch m {
	case modeMajority:
		return pb.ReplicationMode_MAJORITY
	case modeDRAutoSync:
		return pb.ReplicationMode_DR_AUTO_SYNC
	}
	return 0
}
type FileReplicater interface {
	ReplicateFileToAllMembers(ctx context.Context, name string, data []byte) error
}
const drStatusFile = "DR_STATE"
const persistFileTimeout = time.Second * 10
type ModeManager struct {
	initTime time.Time
	sync.RWMutex
	config         config.ReplicationModeConfig
	storage        *core.Storage
	cluster        opt.Cluster
	fileReplicater FileReplicater
	drAutoSync drAutoSyncStatus
	drRecoverKey   []byte  
	drRecoverCount int     
	drSampleRecoverCount int  
	drSampleTotalRegion  int  
	drTotalRegion        int  
	drMemberWaitAsyncTime map[uint64]time.Time  
}
func NewReplicationModeManager(config config.ReplicationModeConfig, storage *core.Storage, cluster opt.Cluster, fileReplicater FileReplicater) (*ModeManager, error) {
	m := &ModeManager{
		initTime:              time.Now(),
		config:                config,
		storage:               storage,
		cluster:               cluster,
		fileReplicater:        fileReplicater,
		drMemberWaitAsyncTime: make(map[uint64]time.Time),
	}
	switch config.ReplicationMode {
	case modeMajority:
	case modeDRAutoSync:
		if err := m.loadDRAutoSync(); err != nil {
			return nil, err
		}
	}
	return m, nil
}