Skip to content

Commit 4f9f7fe

Browse files
WilliamLu99shanth96
authored andcommitted
Fix convertBoolToSemiSyncAction method to account for all semi sync actions
Signed-off-by: William Lu <[email protected]>
1 parent 62859af commit 4f9f7fe

File tree

7 files changed

+65
-12
lines changed

7 files changed

+65
-12
lines changed

go/test/endtoend/reparent/plannedreparent/reparent_test.go

+35
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,41 @@ func TestChangeTypeSemiSync(t *testing.T) {
360360
utils.CheckDBstatus(ctx, t, rdonly2, "Rpl_semi_sync_slave_status", "ON")
361361
}
362362

363+
// Tests that ChangeTabletType works even when semi-sync plugins are not loaded.
364+
func TestChangeTypeWithoutSemiSync(t *testing.T) {
365+
defer cluster.PanicHandler(t)
366+
clusterInstance := utils.SetupReparentCluster(t, "none")
367+
defer utils.TeardownCluster(clusterInstance)
368+
tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets
369+
370+
ctx := context.Background()
371+
372+
primary, replica := tablets[0], tablets[1]
373+
374+
// Unload semi sync plugins
375+
for _, tablet := range tablets[0:4] {
376+
qr := utils.RunSQL(ctx, t, "select @@global.super_read_only", tablet)
377+
result := fmt.Sprintf("%v", qr.Rows[0][0].ToString())
378+
if result == "1" {
379+
utils.RunSQL(ctx, t, "set global super_read_only = 0", tablet)
380+
}
381+
382+
utils.RunSQL(ctx, t, "UNINSTALL PLUGIN rpl_semi_sync_slave;", tablet)
383+
utils.RunSQL(ctx, t, "UNINSTALL PLUGIN rpl_semi_sync_master;", tablet)
384+
}
385+
386+
utils.ValidateTopology(t, clusterInstance, true)
387+
utils.CheckPrimaryTablet(t, clusterInstance, primary)
388+
389+
// Change replica's type to rdonly
390+
err := clusterInstance.VtctlclientProcess.ExecuteCommand("ChangeTabletType", replica.Alias, "rdonly")
391+
require.NoError(t, err)
392+
393+
// Change tablets type from rdonly back to replica
394+
err = clusterInstance.VtctlclientProcess.ExecuteCommand("ChangeTabletType", replica.Alias, "replica")
395+
require.NoError(t, err)
396+
}
397+
363398
func TestReparentDoesntHangIfPrimaryFails(t *testing.T) {
364399
utilstest.SkipIfBinaryIsAboveVersion(t, 15, "vttablet")
365400

go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go

+5
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,11 @@ func (fmd *FakeMysqlDaemon) SemiSyncClients() uint32 {
643643
return 0
644644
}
645645

646+
// SemiSyncExtensionLoaded is part of the MysqlDaemon interface.
647+
func (fmd *FakeMysqlDaemon) SemiSyncExtensionLoaded() bool {
648+
return true
649+
}
650+
646651
// SemiSyncSettings is part of the MysqlDaemon interface.
647652
func (fmd *FakeMysqlDaemon) SemiSyncSettings() (timeout uint64, numReplicas uint32) {
648653
return 10000000, 1

go/vt/mysqlctl/mysql_daemon.go

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type MysqlDaemon interface {
5757
GetGTIDPurged(ctx context.Context) (mysql.Position, error)
5858
SetSemiSyncEnabled(source, replica bool) error
5959
SemiSyncEnabled() (source, replica bool)
60+
SemiSyncExtensionLoaded() bool
6061
SemiSyncStatus() (source, replica bool)
6162
SemiSyncClients() (count uint32)
6263
SemiSyncSettings() (timeout uint64, numReplicas uint32)

go/vt/mysqlctl/replication.go

+9
Original file line numberDiff line numberDiff line change
@@ -664,3 +664,12 @@ func (mysqld *Mysqld) SemiSyncReplicationStatus() (bool, error) {
664664
}
665665
return false, nil
666666
}
667+
668+
func (mysqld *Mysqld) SemiSyncExtensionLoaded() bool {
669+
qr, err := mysqld.FetchSuperQuery(context.TODO(), "SELECT COUNT(*) > 0 AS plugin_loaded FROM information_schema.plugins WHERE plugin_name LIKE 'rpl_semi_sync%'")
670+
if err != nil {
671+
return false
672+
}
673+
pluginPresent, _ := qr.Rows[0][0].ToBool()
674+
return pluginPresent
675+
}

go/vt/vttablet/tabletmanager/rpc_actions.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func (tm *TabletManager) ChangeType(ctx context.Context, tabletType topodatapb.T
8282
return err
8383
}
8484
defer tm.unlock()
85-
return tm.changeTypeLocked(ctx, tabletType, DBActionNone, convertBoolToSemiSyncAction(semiSync))
85+
return tm.changeTypeLocked(ctx, tabletType, DBActionNone, tm.convertBoolToSemiSyncAction(semiSync))
8686
}
8787

8888
// ChangeType changes the tablet type
@@ -142,9 +142,12 @@ func (tm *TabletManager) RunHealthCheck(ctx context.Context) {
142142
tm.QueryServiceControl.BroadcastHealth()
143143
}
144144

145-
func convertBoolToSemiSyncAction(semiSync bool) SemiSyncAction {
145+
func (tm *TabletManager) convertBoolToSemiSyncAction(semiSync bool) SemiSyncAction {
146146
if semiSync {
147147
return SemiSyncActionSet
148148
}
149-
return SemiSyncActionUnset
149+
if tm.MysqlDaemon.SemiSyncExtensionLoaded() {
150+
return SemiSyncActionUnset
151+
}
152+
return SemiSyncActionNone
150153
}

go/vt/vttablet/tabletmanager/rpc_replication.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ func (tm *TabletManager) StartReplication(ctx context.Context, semiSync bool) er
294294
}
295295
}()
296296

297-
if err := tm.fixSemiSync(tm.Tablet().Type, convertBoolToSemiSyncAction(semiSync)); err != nil {
297+
if err := tm.fixSemiSync(tm.Tablet().Type, tm.convertBoolToSemiSyncAction(semiSync)); err != nil {
298298
return err
299299
}
300300
return tm.MysqlDaemon.StartReplication(tm.hookExtraEnv())
@@ -380,13 +380,13 @@ func (tm *TabletManager) InitPrimary(ctx context.Context, semiSync bool) (string
380380
// Set the server read-write, from now on we can accept real
381381
// client writes. Note that if semi-sync replication is enabled,
382382
// we'll still need some replicas to be able to commit transactions.
383-
if err := tm.changeTypeLocked(ctx, topodatapb.TabletType_PRIMARY, DBActionSetReadWrite, convertBoolToSemiSyncAction(semiSync)); err != nil {
383+
if err := tm.changeTypeLocked(ctx, topodatapb.TabletType_PRIMARY, DBActionSetReadWrite, tm.convertBoolToSemiSyncAction(semiSync)); err != nil {
384384
return "", err
385385
}
386386

387387
// Enforce semi-sync after changing the tablet)type to PRIMARY. Otherwise, the
388388
// primary will hang while trying to create the database.
389-
if err := tm.fixSemiSync(topodatapb.TabletType_PRIMARY, convertBoolToSemiSyncAction(semiSync)); err != nil {
389+
if err := tm.fixSemiSync(topodatapb.TabletType_PRIMARY, tm.convertBoolToSemiSyncAction(semiSync)); err != nil {
390390
return "", err
391391
}
392392

@@ -427,7 +427,7 @@ func (tm *TabletManager) InitReplica(ctx context.Context, parent *topodatapb.Tab
427427
// is used on the old primary when using InitShardPrimary with
428428
// -force, and the new primary is different from the old primary.
429429
if tm.Tablet().Type == topodatapb.TabletType_PRIMARY {
430-
if err := tm.changeTypeLocked(ctx, topodatapb.TabletType_REPLICA, DBActionNone, convertBoolToSemiSyncAction(semiSync)); err != nil {
430+
if err := tm.changeTypeLocked(ctx, topodatapb.TabletType_REPLICA, DBActionNone, tm.convertBoolToSemiSyncAction(semiSync)); err != nil {
431431
return err
432432
}
433433
}
@@ -450,7 +450,7 @@ func (tm *TabletManager) InitReplica(ctx context.Context, parent *topodatapb.Tab
450450
if tt == topodatapb.TabletType_PRIMARY {
451451
tt = topodatapb.TabletType_REPLICA
452452
}
453-
if err := tm.fixSemiSync(tt, convertBoolToSemiSyncAction(semiSync)); err != nil {
453+
if err := tm.fixSemiSync(tt, tm.convertBoolToSemiSyncAction(semiSync)); err != nil {
454454
return err
455455
}
456456

@@ -602,7 +602,7 @@ func (tm *TabletManager) UndoDemotePrimary(ctx context.Context, semiSync bool) e
602602
defer tm.unlock()
603603

604604
// If using semi-sync, we need to enable source-side.
605-
if err := tm.fixSemiSync(topodatapb.TabletType_PRIMARY, convertBoolToSemiSyncAction(semiSync)); err != nil {
605+
if err := tm.fixSemiSync(topodatapb.TabletType_PRIMARY, tm.convertBoolToSemiSyncAction(semiSync)); err != nil {
606606
return err
607607
}
608608

@@ -672,7 +672,7 @@ func (tm *TabletManager) SetReplicationSource(ctx context.Context, parentAlias *
672672

673673
// setReplicationSourceLocked also fixes the semi-sync. In case the tablet type is primary it assumes that it will become a replica if SetReplicationSource
674674
// is called, so we always call fixSemiSync with a non-primary tablet type. This will always set the source side replication to false.
675-
return tm.setReplicationSourceLocked(ctx, parentAlias, timeCreatedNS, waitPosition, forceStartReplication, convertBoolToSemiSyncAction(semiSync))
675+
return tm.setReplicationSourceLocked(ctx, parentAlias, timeCreatedNS, waitPosition, forceStartReplication, tm.convertBoolToSemiSyncAction(semiSync))
676676
}
677677

678678
func (tm *TabletManager) setReplicationSourceRepairReplication(ctx context.Context, parentAlias *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartReplication bool) (err error) {
@@ -965,7 +965,7 @@ func (tm *TabletManager) PromoteReplica(ctx context.Context, semiSync bool) (str
965965
}
966966

967967
// If using semi-sync, we need to enable it before going read-write.
968-
if err := tm.fixSemiSync(topodatapb.TabletType_PRIMARY, convertBoolToSemiSyncAction(semiSync)); err != nil {
968+
if err := tm.fixSemiSync(topodatapb.TabletType_PRIMARY, tm.convertBoolToSemiSyncAction(semiSync)); err != nil {
969969
return "", err
970970
}
971971

go/vt/vttablet/tabletmanager/tm_init.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,7 @@ func (tm *TabletManager) initializeReplication(ctx context.Context, tabletType t
910910
// If using semi-sync, we need to enable it before connecting to primary.
911911
// We should set the correct type, since it is used in replica semi-sync
912912
tablet.Type = tabletType
913-
if err := tm.fixSemiSync(tabletType, convertBoolToSemiSyncAction(reparentutil.IsReplicaSemiSync(durability, currentPrimary.Tablet, tablet))); err != nil {
913+
if err := tm.fixSemiSync(tabletType, tm.convertBoolToSemiSyncAction(reparentutil.IsReplicaSemiSync(durability, currentPrimary.Tablet, tablet))); err != nil {
914914
return nil, err
915915
}
916916

0 commit comments

Comments
 (0)