@@ -1133,7 +1133,11 @@ func (app *App) updateActiveNodes(clusterState, clusterStateDcs map[string]*node
11331133 node := app .cluster .Get (host )
11341134 app .disableSemiSyncIfNonNeeded (node , state )
11351135 }
1136- // than update DCS
1136+ // then update DCS
1137+ if ! app .canShrinkActiveNodes (masterNode , oldActiveNodes , activeNodes ) {
1138+ app .logger .Error ().Err (err ).Msg ("update active nodes: failed to update active nodes, master is dead" )
1139+ return nil
1140+ }
11371141 err = app .dcs .Set (pathActiveNodes , activeNodes )
11381142 if err != nil {
11391143 app .logger .Error ().Err (err ).Msg ("update active nodes: failed to update active nodes in dcs" )
@@ -1208,7 +1212,11 @@ func (app *App) updateActiveNodes(clusterState, clusterStateDcs map[string]*node
12081212 }
12091213 }
12101214
1211- // than update DCS
1215+ // then update DCS
1216+ if ! app .canShrinkActiveNodes (masterNode , oldActiveNodes , activeNodes ) {
1217+ app .logger .Error ().Err (err ).Msg ("update active nodes: failed to update active nodes in dcs" )
1218+ return nil
1219+ }
12121220 err = app .dcs .Set (pathActiveNodes , activeNodes )
12131221 if err != nil {
12141222 app .logger .Error ().Err (err ).Msg ("update active nodes: failed to update active nodes in dcs" )
@@ -1218,6 +1226,21 @@ func (app *App) updateActiveNodes(clusterState, clusterStateDcs map[string]*node
12181226 return nil
12191227}
12201228
1229+ // Check that we can safely remove nodes from active nodes
1230+ // Can't switch if master is dying, because we won't be able
1231+ // to perform failovers
1232+ func (app * App ) canShrinkActiveNodes (masterNode * mysql.Node , oldActiveNodes , newActiveNodes []string ) bool {
1233+ removed := filterOut (oldActiveNodes , newActiveNodes )
1234+ if len (removed ) == 0 {
1235+ return true // not shrinking (adding hosts or no change) - always safe
1236+ }
1237+ if ok , err := masterNode .Ping (); ! ok {
1238+ app .logger .Error ().Err (err ).Msgf ("update active nodes: master %s is not alive, will not evict %v from active nodes" , masterNode .Host (), removed )
1239+ return false
1240+ }
1241+ return true
1242+ }
1243+
12211244func (app * App ) adjustSemiSyncOnMaster (node * mysql.Node , state * nodestate.NodeState , waitSlaveCount int ) error {
12221245 if state .SemiSyncState == nil {
12231246 return fmt .Errorf ("semi-sync state is empty for %s" , node .Host ())
0 commit comments