From d755677b7d31f21b986e05b599ddaa31bff510a7 Mon Sep 17 00:00:00 2001 From: secwall Date: Mon, 13 May 2024 18:50:42 +0500 Subject: [PATCH] Optionally allow turning psync-able replicas to new master before promote --- .github/workflows/golangci-lint.yml | 2 +- Makefile | 2 +- internal/app/switchover.go | 27 +++++++++++++++++++++++++++ internal/config/config.go | 2 ++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 315f8a8..6ea51bf 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -24,4 +24,4 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v6 with: - version: v1.55 + version: v1.58 diff --git a/Makefile b/Makefile index c956062..263068a 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ format: goimports -w `find . -name '*.go'` lint: - docker run --rm -v ${CURDIR}:/app -w /app golangci/golangci-lint:v1.55-alpine golangci-lint run -v + docker run --rm -v ${CURDIR}:/app -w /app golangci/golangci-lint:v1.58-alpine golangci-lint run -v unittests: go test ./cmd/... ./internal/... diff --git a/internal/app/switchover.go b/internal/app/switchover.go index dad5037..c32e429 100644 --- a/internal/app/switchover.go +++ b/internal/app/switchover.go @@ -354,6 +354,33 @@ func (app *App) performSwitchover(shardState map[string]*HostState, activeNodes app.waitPoisonPill(app.config.Redis.WaitPoisonPillTimeout) } + if app.config.Redis.TurnBeforeSwitchover { + var psyncNodes []string + for _, host := range aliveActiveNodes { + if host == newMaster { + continue + } + if isPartialSyncPossible(shardState[host], shardState[newMaster]) { + psyncNodes = append(psyncNodes, host) + } + } + + errs := runParallel(func(host string) error { + if !shardState[host].PingOk { + return nil + } + err := app.changeMaster(host, newMaster) + if err != nil { + return err + } + return nil + }, psyncNodes) + + err := combineErrors(errs) + if err != nil { + app.logger.Warn("Unable to psync some replicas before promote", "error", err) + } + } deadline := time.Now().Add(app.config.Redis.WaitPromoteTimeout) forceDeadline := time.Now().Add(app.config.Redis.WaitPromoteForceTimeout) promoted := false diff --git a/internal/config/config.go b/internal/config/config.go index 702ee0d..93ccaa2 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -35,6 +35,7 @@ type RedisConfig struct { MaxParallelSyncs int `yaml:"max_parallel_syncs"` MaxReplicasToWrite int `yaml:"max_replicas_to_write"` AllowDataLoss bool `yaml:"allow_data_loss"` + TurnBeforeSwitchover bool `yaml:"turn_before_switchover"` RestartCommand string `yaml:"restart_command"` } @@ -108,6 +109,7 @@ func DefaultRedisConfig() RedisConfig { MaxParallelSyncs: 1, MaxReplicasToWrite: -1, AllowDataLoss: false, + TurnBeforeSwitchover: false, RestartCommand: "systemctl restart redis-server", } }