From 4d0445d66812455718f9c802da3d4225baef3657 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 17 Sep 2021 19:56:45 +0800 Subject: [PATCH 1/4] fix: graceful-auto candidate error Signed-off-by: root --- go/inst/instance_topology.go | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/go/inst/instance_topology.go b/go/inst/instance_topology.go index 26b93113b..30c9dac92 100644 --- a/go/inst/instance_topology.go +++ b/go/inst/instance_topology.go @@ -2202,6 +2202,31 @@ func getPriorityBinlogFormatForCandidate(replicas [](*Instance)) (priorityBinlog return sorted.First(), nil } +func getPriorityDataCenterForCandidate(replica [](*Instance)) (priorityDataCenter string, err error) { + if len(replicas) == 0 { + return "", log.Errorf("empty replicas list in getPriorityBinlogFormatForCandidate") + } + candidate := "" + for _, replica := range { + candidate = replica.DataCenter + return candidate, nil + } + return "", nil +} + + +func IsDataCenterCandiadateReplica(priorityDataCenter string, replica *Instance) bool { + masterOfDesignatedInstance, _ := GetInstanceMaster(replica) + if masterOfDesignatedInstance.DataCenter == priorityDataCenter { + log.Debugf("instance %+v is banned because of promotion rule", replica.Key) + return true + } + if matched, _ := regexp.MatchString(config.Config.DataCenterPattern, replica.Key.Hostname); matched { + return true + } + return false +} + // chooseCandidateReplica func chooseCandidateReplica(replicas [](*Instance)) (candidateReplica *Instance, aheadReplicas, equalReplicas, laterReplicas, cannotReplicateReplicas [](*Instance), err error) { if len(replicas) == 0 { @@ -2209,13 +2234,14 @@ func chooseCandidateReplica(replicas [](*Instance)) (candidateReplica *Instance, } priorityMajorVersion, _ := getPriorityMajorVersionForCandidate(replicas) priorityBinlogFormat, _ := getPriorityBinlogFormatForCandidate(replicas) - + priorityDataCenter, _ := getPriorityDataCenterForCandidate(replicas) for _, replica := range replicas { replica := replica if isGenerallyValidAsCandidateReplica(replica) && !IsBannedFromBeingCandidateReplica(replica) && !IsSmallerMajorVersion(priorityMajorVersion, replica.MajorVersionString()) && - !IsSmallerBinlogFormat(priorityBinlogFormat, replica.Binlog_format) { + !IsSmallerBinlogFormat(priorityBinlogFormat, replica.Binlog_format) && + IsDataCenterCandiadateReplica(priorityDataCenter, replica) { // this is the one candidateReplica = replica break From 373287a9a602eb475f4ce5696a8c07944967d3db Mon Sep 17 00:00:00 2001 From: baijiu1 Date: Fri, 17 Sep 2021 20:43:59 +0800 Subject: [PATCH 2/4] fix: graceful-auto candidate error Signed-off-by: baijiu1 --- go/inst/instance_topology.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/inst/instance_topology.go b/go/inst/instance_topology.go index 30c9dac92..f3abe7f2e 100644 --- a/go/inst/instance_topology.go +++ b/go/inst/instance_topology.go @@ -2202,12 +2202,12 @@ func getPriorityBinlogFormatForCandidate(replicas [](*Instance)) (priorityBinlog return sorted.First(), nil } -func getPriorityDataCenterForCandidate(replica [](*Instance)) (priorityDataCenter string, err error) { +func getPriorityDataCenterForCandidate(replicas [](*Instance)) (priorityDataCenter string, err error) { if len(replicas) == 0 { return "", log.Errorf("empty replicas list in getPriorityBinlogFormatForCandidate") } candidate := "" - for _, replica := range { + for _, replica := range replicas { candidate = replica.DataCenter return candidate, nil } From 13faefddab7e8bb050bc68cb156ff2762177de0c Mon Sep 17 00:00:00 2001 From: baijiu1 Date: Fri, 17 Sep 2021 21:09:58 +0800 Subject: [PATCH 3/4] fix: graceful-auto candidate error Signed-off-by: baijiu1 --- go/inst/instance_topology.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/go/inst/instance_topology.go b/go/inst/instance_topology.go index f3abe7f2e..02f3894da 100644 --- a/go/inst/instance_topology.go +++ b/go/inst/instance_topology.go @@ -2202,6 +2202,8 @@ func getPriorityBinlogFormatForCandidate(replicas [](*Instance)) (priorityBinlog return sorted.First(), nil } +// getPriorityDataCenterForCandidate returns the replica datacenter found +// among given instances. This will be used for choosing best candidate for promotion. func getPriorityDataCenterForCandidate(replicas [](*Instance)) (priorityDataCenter string, err error) { if len(replicas) == 0 { return "", log.Errorf("empty replicas list in getPriorityBinlogFormatForCandidate") @@ -2214,7 +2216,8 @@ func getPriorityDataCenterForCandidate(replicas [](*Instance)) (priorityDataCent return "", nil } - +// IsDataCenterCandiadateReplica compare master's datacenter and replica datacenter. +// if master's datacenter eq replica datacenter return true func IsDataCenterCandiadateReplica(priorityDataCenter string, replica *Instance) bool { masterOfDesignatedInstance, _ := GetInstanceMaster(replica) if masterOfDesignatedInstance.DataCenter == priorityDataCenter { @@ -2234,7 +2237,10 @@ func chooseCandidateReplica(replicas [](*Instance)) (candidateReplica *Instance, } priorityMajorVersion, _ := getPriorityMajorVersionForCandidate(replicas) priorityBinlogFormat, _ := getPriorityBinlogFormatForCandidate(replicas) + // priorityDataCenter return boll for candidate priorityDataCenter, _ := getPriorityDataCenterForCandidate(replicas) + + for _, replica := range replicas { replica := replica if isGenerallyValidAsCandidateReplica(replica) && From 3aabd6aaaf1208cfc15872e73250449d0cd5dcf2 Mon Sep 17 00:00:00 2001 From: haruhi Date: Fri, 17 Sep 2021 21:45:30 +0800 Subject: [PATCH 4/4] Update instance_topology.go add PreventCrossDataCenterMasterFailover decide --- go/inst/instance_topology.go | 38 ++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/go/inst/instance_topology.go b/go/inst/instance_topology.go index 02f3894da..e02e68d91 100644 --- a/go/inst/instance_topology.go +++ b/go/inst/instance_topology.go @@ -2241,18 +2241,32 @@ func chooseCandidateReplica(replicas [](*Instance)) (candidateReplica *Instance, priorityDataCenter, _ := getPriorityDataCenterForCandidate(replicas) - for _, replica := range replicas { - replica := replica - if isGenerallyValidAsCandidateReplica(replica) && - !IsBannedFromBeingCandidateReplica(replica) && - !IsSmallerMajorVersion(priorityMajorVersion, replica.MajorVersionString()) && - !IsSmallerBinlogFormat(priorityBinlogFormat, replica.Binlog_format) && - IsDataCenterCandiadateReplica(priorityDataCenter, replica) { - // this is the one - candidateReplica = replica - break - } - } + if config.Config.PreventCrossDataCenterMasterFailover { + for _, replica := range replicas { + replica := replica + if isGenerallyValidAsCandidateReplica(replica) && + !IsBannedFromBeingCandidateReplica(replica) && + !IsSmallerMajorVersion(priorityMajorVersion, replica.MajorVersionString()) && + !IsSmallerBinlogFormat(priorityBinlogFormat, replica.Binlog_format) && + IsDataCenterCandiadateReplica(priorityDataCenter, replica) { + // this is the one + candidateReplica = replica + break + } + } + } else { + for _, replica := range replicas { + replica := replica + if isGenerallyValidAsCandidateReplica(replica) && + !IsBannedFromBeingCandidateReplica(replica) && + !IsSmallerMajorVersion(priorityMajorVersion, replica.MajorVersionString()) && + !IsSmallerBinlogFormat(priorityBinlogFormat, replica.Binlog_format) { + // this is the one + candidateReplica = replica + break + } + } + } if candidateReplica == nil { // Unable to find a candidate that will master others. // Instead, pick a (single) replica which is not banned.