Skip to content

Commit 5dfa17d

Browse files
DISTMYSQL-138: MySQL Orchestrator does not support
new semi-sync variables introduced in MySQL 8.0.26 https://jira.percona.com/browse/DISTMYSQL-138 Problem: MySql 8.0.26 introduced new semisync replication plugins semisync_source.so and semisync_replica.so in place of semisync_master.so and semisync_slave.so All semisync replication plugins' variables were renamed in the way that 'master' was replaced with the term 'source' and 'slave' was replaced by 'replica'. As 8.0.26 contains also old plugins and when they are installed everything works fine it is not enough to detect server version. Moreover, it is possible to mix old source plugin with new replica plugin and the opposite. Solution: Detect which plugins are installed and use proper variable names.
1 parent 0d032dd commit 5dfa17d

File tree

9 files changed

+103
-13
lines changed

9 files changed

+103
-13
lines changed

go/http/api.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ var apiSynonyms = map[string]string{
7575
"stop-slave-nice": "stop-replica-nice",
7676
"reset-slave": "reset-replica",
7777
"restart-slave-statements": "restart-replica-statements",
78+
"enable-semi-sync-master": "enable-semi-sync-source",
79+
"disable-semi-sync-master": "disable-semi-sync-source",
7880
}
7981

8082
var registeredPaths = []string{}

go/inst/instance.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ type Instance struct {
9595
ReplicationCredentialsAvailable bool
9696
SemiSyncAvailable bool // when both semi sync plugins (master & replica) are loaded
9797
SemiSyncPriority uint // higher value means higher priority, zero means async replica
98+
SemiSyncMasterPluginNewVersion bool // true for the plugin introduced with MySql 8.0.26
99+
SemiSyncReplicaPluginNewVersion bool // true for the plugin introduced with MySql 8.0.26
98100
SemiSyncMasterEnabled bool
99101
SemiSyncReplicaEnabled bool
100102
SemiSyncMasterTimeout uint64

go/inst/instance_dao.go

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"database/sql"
2222
"errors"
2323
"fmt"
24-
"github.com/go-sql-driver/mysql"
2524
"regexp"
2625
"runtime"
2726
"sort"
@@ -30,6 +29,8 @@ import (
3029
"sync"
3130
"time"
3231

32+
"github.com/go-sql-driver/mysql"
33+
3334
"github.com/openark/golib/log"
3435
"github.com/openark/golib/math"
3536
"github.com/openark/golib/sqlutils"
@@ -463,20 +464,54 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool,
463464
defer waitGroup.Done()
464465
semiSyncMasterPluginLoaded := false
465466
semiSyncReplicaPluginLoaded := false
467+
instance.SemiSyncAvailable = false
468+
466469
err := sqlutils.QueryRowsMap(db, "show global variables like 'rpl_semi_sync_%'", func(m sqlutils.RowMap) error {
467-
if m.GetString("Variable_name") == "rpl_semi_sync_master_enabled" {
470+
variableName := m.GetString("Variable_name")
471+
// Learn if semi-sync plugin is loaded and what is its version
472+
if variableName == "rpl_semi_sync_master_enabled" {
468473
instance.SemiSyncMasterEnabled = (m.GetString("Value") == "ON")
469474
semiSyncMasterPluginLoaded = true
470-
} else if m.GetString("Variable_name") == "rpl_semi_sync_master_timeout" {
471-
instance.SemiSyncMasterTimeout = m.GetUint64("Value")
472-
} else if m.GetString("Variable_name") == "rpl_semi_sync_master_wait_for_slave_count" {
473-
instance.SemiSyncMasterWaitForReplicaCount = m.GetUint("Value")
474-
} else if m.GetString("Variable_name") == "rpl_semi_sync_slave_enabled" {
475+
instance.SemiSyncMasterPluginNewVersion = false
476+
} else if variableName == "rpl_semi_sync_source_enabled" {
477+
instance.SemiSyncMasterEnabled = (m.GetString("Value") == "ON")
478+
semiSyncMasterPluginLoaded = true
479+
instance.SemiSyncMasterPluginNewVersion = true
480+
} else if variableName == "rpl_semi_sync_slave_enabled" {
475481
instance.SemiSyncReplicaEnabled = (m.GetString("Value") == "ON")
476482
semiSyncReplicaPluginLoaded = true
483+
instance.SemiSyncReplicaPluginNewVersion = false
484+
} else if variableName == "rpl_semi_sync_replica_enabled" {
485+
instance.SemiSyncReplicaEnabled = (m.GetString("Value") == "ON")
486+
semiSyncReplicaPluginLoaded = true
487+
instance.SemiSyncReplicaPluginNewVersion = true
488+
} else {
489+
// additional info
490+
matched, regexperr := regexp.MatchString("^rpl_semi_sync_(master|source)_timeout$", variableName)
491+
if regexperr != nil {
492+
return regexperr
493+
}
494+
if matched {
495+
instance.SemiSyncMasterTimeout = m.GetUint64("Value")
496+
return nil
497+
}
498+
499+
matched, regexperr = regexp.MatchString("^rpl_semi_sync_(master|source)_wait_for_(slave|replica)_count$", variableName)
500+
if regexperr != nil {
501+
return regexperr
502+
}
503+
if matched {
504+
instance.SemiSyncMasterWaitForReplicaCount = m.GetUint("Value")
505+
return nil
506+
}
477507
}
478508
return nil
479509
})
510+
if err != nil {
511+
errorChan <- err
512+
return
513+
}
514+
480515
instance.SemiSyncAvailable = (semiSyncMasterPluginLoaded && semiSyncReplicaPluginLoaded)
481516
errorChan <- err
482517
}()
@@ -486,14 +521,32 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool,
486521
go func() {
487522
defer waitGroup.Done()
488523
err := sqlutils.QueryRowsMap(db, "show global status like 'rpl_semi_sync_%'", func(m sqlutils.RowMap) error {
489-
if m.GetString("Variable_name") == "Rpl_semi_sync_master_status" {
524+
variableName := m.GetString("Variable_name")
525+
matched, regexperr := regexp.MatchString("^Rpl_semi_sync_(master|source)_status$", variableName)
526+
if regexperr != nil {
527+
return regexperr
528+
}
529+
if matched {
490530
instance.SemiSyncMasterStatus = (m.GetString("Value") == "ON")
491-
} else if m.GetString("Variable_name") == "Rpl_semi_sync_master_clients" {
531+
return nil
532+
}
533+
534+
matched, regexperr = regexp.MatchString("^Rpl_semi_sync_(master|source)_clients$", variableName)
535+
if regexperr != nil {
536+
return regexperr
537+
}
538+
if matched {
492539
instance.SemiSyncMasterClients = m.GetUint("Value")
493-
} else if m.GetString("Variable_name") == "Rpl_semi_sync_slave_status" {
494-
instance.SemiSyncReplicaStatus = (m.GetString("Value") == "ON")
540+
return nil
495541
}
496542

543+
matched, regexperr = regexp.MatchString("^Rpl_semi_sync_(slave|replica)_status$", variableName)
544+
if regexperr != nil {
545+
return regexperr
546+
}
547+
if matched {
548+
instance.SemiSyncReplicaStatus = (m.GetString("Value") == "ON")
549+
}
497550
return nil
498551
})
499552
errorChan <- err

go/inst/instance_topology_dao.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,11 @@ func SetSemiSyncMaster(instanceKey *InstanceKey, enableMaster bool) (*Instance,
223223
if err != nil {
224224
return instance, err
225225
}
226-
if _, err := ExecInstance(instanceKey, "set @@global.rpl_semi_sync_master_enabled=?", enableMaster); err != nil {
226+
query := "set @@global.rpl_semi_sync_master_enabled=?"
227+
if instance.SemiSyncMasterPluginNewVersion {
228+
query = "set @@global.rpl_semi_sync_source_enabled=?"
229+
}
230+
if _, err := ExecInstance(instanceKey, query, enableMaster); err != nil {
227231
return instance, log.Errore(err)
228232
}
229233
return ReadTopologyInstance(instanceKey)
@@ -237,7 +241,13 @@ func SetSemiSyncReplica(instanceKey *InstanceKey, enableReplica bool) (*Instance
237241
if instance.SemiSyncReplicaEnabled == enableReplica {
238242
return instance, nil
239243
}
240-
if _, err := ExecInstance(instanceKey, "set @@global.rpl_semi_sync_slave_enabled=?", enableReplica); err != nil {
244+
245+
query := "set @@global.rpl_semi_sync_slave_enabled=?"
246+
if instance.SemiSyncReplicaPluginNewVersion {
247+
query = "set @@global.rpl_semi_sync_replica_enabled=?"
248+
}
249+
250+
if _, err := ExecInstance(instanceKey, query, enableReplica); err != nil {
241251
return instance, log.Errore(err)
242252
}
243253
if instance.ReplicationIOThreadRuning {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
127.0.0.1:10111 [0s,ok,VERSION,rw,ROW,>>,GTID,semi:master]
2+
+ 127.0.0.1:10112 [0s,ok,VERSION,ro,ROW,>>,GTID,semi:replica]
3+
+ 127.0.0.1:10113 [0s,ok,VERSION,ro,ROW,>>,GTID,semi:replica]
4+
+ 127.0.0.1:10114 [0s,ok,VERSION,ro,ROW,>>,GTID,semi:replica]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# sed is to get rid of MySql version from the output
2+
orchestrator-client -c topology -i 127.0.0.1:10111 | sed -n "s/\(^.*0s,ok,\)\s*\S*\(,r.,.*$\)/\1VERSION\2/p"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
orchestrator-client -c enable-semi-sync-master -i 127.0.0.1:10111
6+
orchestrator-client -c enable-semi-sync-replica -i 127.0.0.1:10112
7+
orchestrator-client -c enable-semi-sync-replica -i 127.0.0.1:10113
8+
orchestrator-client -c enable-semi-sync-replica -i 127.0.0.1:10114
9+
sleep 10

tests/system/semi-sync/skip_run

Whitespace-only changes.

tests/system/semi-sync/teardown

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
3+
orchestrator-client -c all-instances | while read i ; do
4+
orchestrator-client -c disable-semi-sync-master -i $i
5+
orchestrator-client -c disable-semi-sync-replica -i $i
6+
done
7+
8+
sleep 5

0 commit comments

Comments
 (0)