Skip to content
This repository was archived by the owner on Feb 18, 2025. It is now read-only.

Commit e6a8067

Browse files
author
Shlomi Noach
authored
Merge pull request #92 from github/independent-multi-match
Independent multi-match
2 parents 68e1e28 + a74e1c0 commit e6a8067

File tree

4 files changed

+58
-1
lines changed

4 files changed

+58
-1
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ vagrant/db4-post-install.sh
1010
vagrant/vagrant-ssh-key
1111
vagrant/vagrant-ssh-key.pub
1212
Godeps/_workspace
13+
main

RELEASE_VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.2
1+
2.0.3

go/config/config.go

+2
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ type Configuration struct {
160160
PseudoGTIDMonotonicHint string // subtring in Pseudo-GTID entry which indicates Pseudo-GTID entries are expected to be monotonically increasing
161161
DetectPseudoGTIDQuery string // Optional query which is used to authoritatively decide whether pseudo gtid is enabled on instance
162162
PseudoGTIDCoordinatesHistoryHeuristicMinutes int // Significantly reducing Pseudo-GTID lookup time, this indicates the most recent N minutes binlog position where search for Pseudo-GTID will heuristically begin (there is a fallback on fullscan if unsuccessful)
163+
PseudoGTIDPreferIndependentMultiMatch bool // if 'false', a multi-replica Pseudo-GTID operation will attempt grouping replicas via Pseudo-GTID, and make less binlog computations. However it may cause servers in same bucket wait for one another, which could delay some servers from being repointed. There is a tradeoff between total operation time for all servers, and per-server time. When 'true', Pseudo-GTID matching will operate per server, independently. This will cause waste of same calculations, but no two servers will wait on one another.
163164
BinlogEventsChunkSize int // Chunk size (X) for SHOW BINLOG|RELAYLOG EVENTS LIMIT ?,X statements. Smaller means less locking and mroe work to be done
164165
BufferBinlogEvents bool // Should we used buffered read on SHOW BINLOG|RELAYLOG EVENTS -- releases the database lock sooner (recommended)
165166
SkipBinlogEventsContaining []string // When scanning/comparing binlogs for Pseudo-GTID, skip entries containing given texts. These are NOT regular expressions (would consume too much CPU while scanning binlogs), just substrings to find.
@@ -323,6 +324,7 @@ func newConfiguration() *Configuration {
323324
PseudoGTIDMonotonicHint: "",
324325
DetectPseudoGTIDQuery: "",
325326
PseudoGTIDCoordinatesHistoryHeuristicMinutes: 2,
327+
PseudoGTIDPreferIndependentMultiMatch: false,
326328
BinlogEventsChunkSize: 10000,
327329
BufferBinlogEvents: true,
328330
SkipBinlogEventsContaining: []string{},

go/inst/instance_topology.go

+54
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"regexp"
2222
"sort"
2323
"strings"
24+
"sync"
2425
"time"
2526

2627
"github.com/github/orchestrator/go/config"
@@ -1695,9 +1696,62 @@ func GetSortedReplicas(masterKey *InstanceKey, stopReplicationMethod StopReplica
16951696
return replicas, err
16961697
}
16971698

1699+
func MultiMatchBelowIndependently(replicas [](*Instance), belowKey *InstanceKey, postponedFunctionsContainer *PostponedFunctionsContainer) (matchedReplicas [](*Instance), belowInstance *Instance, err error, errs []error) {
1700+
replicas = RemoveInstance(replicas, belowKey)
1701+
if len(replicas) == 0 {
1702+
// Nothing to do
1703+
return matchedReplicas, belowInstance, err, errs
1704+
}
1705+
1706+
belowInstance, found, err := ReadInstance(belowKey)
1707+
if err != nil || !found {
1708+
return matchedReplicas, belowInstance, err, errs
1709+
}
1710+
1711+
log.Infof("Will match %+v replicas below %+v via Pseudo-GTID, independently", len(replicas), belowKey)
1712+
1713+
barrier := make(chan *InstanceKey)
1714+
replicaMutex := &sync.Mutex{}
1715+
1716+
for _, replica := range replicas {
1717+
replica := replica
1718+
1719+
// Parallelize repoints
1720+
go func() {
1721+
defer func() { barrier <- &replica.Key }()
1722+
ExecuteOnTopology(func() {
1723+
replica, _, replicaErr := MatchBelow(&replica.Key, belowKey, true)
1724+
1725+
replicaMutex.Lock()
1726+
defer replicaMutex.Unlock()
1727+
1728+
if replicaErr == nil {
1729+
matchedReplicas = append(matchedReplicas, replica)
1730+
} else {
1731+
errs = append(errs, replicaErr)
1732+
}
1733+
})
1734+
}()
1735+
}
1736+
for range replicas {
1737+
<-barrier
1738+
}
1739+
if len(errs) == len(replicas) {
1740+
// All returned with error
1741+
return matchedReplicas, belowInstance, fmt.Errorf("moveReplicasViaGTID: Error on all %+v operations", len(errs)), errs
1742+
}
1743+
AuditOperation("multi-match-below-independent", belowKey, fmt.Sprintf("matched %d/%d replicas below %+v via Pseudo-GTID", len(matchedReplicas), len(replicas), belowKey))
1744+
1745+
return matchedReplicas, belowInstance, err, errs
1746+
1747+
}
1748+
16981749
// MultiMatchBelow will efficiently match multiple replicas below a given instance.
16991750
// It is assumed that all given replicas are siblings
17001751
func MultiMatchBelow(replicas [](*Instance), belowKey *InstanceKey, replicasAlreadyStopped bool, postponedFunctionsContainer *PostponedFunctionsContainer) ([](*Instance), *Instance, error, []error) {
1752+
if config.Config.PseudoGTIDPreferIndependentMultiMatch {
1753+
return MultiMatchBelowIndependently(replicas, belowKey, postponedFunctionsContainer)
1754+
}
17011755
res := [](*Instance){}
17021756
errs := []error{}
17031757
replicaMutex := make(chan bool, 1)

0 commit comments

Comments
 (0)