From 2e0c3c7919c8fe12c5a0b2af176132c2b86e2052 Mon Sep 17 00:00:00 2001 From: runkecheng <1131648942@qq.com> Date: Thu, 2 Jun 2022 10:56:49 +0800 Subject: [PATCH] feat(cluster): actively switch leader to updated pod. --- mysqlcluster/syncer/statefulset.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mysqlcluster/syncer/statefulset.go b/mysqlcluster/syncer/statefulset.go index b1b2150a..0d8f7e1f 100644 --- a/mysqlcluster/syncer/statefulset.go +++ b/mysqlcluster/syncer/statefulset.go @@ -328,10 +328,14 @@ func (s *StatefulSetSyncer) updatePod(ctx context.Context) error { return err } var leaderPod corev1.Pod + // newLeader saves the nodes (follower) that have been updated. + // The old leader will switch the leader to the newLeader after all follower nodes are updated. + newLeader := "" for _, pod := range pods.Items { // Check if the pod is healthy. if pod.ObjectMeta.Labels["healthy"] != "yes" { - return fmt.Errorf("can't start/continue 'update': pod[%s] is unhealthy", pod.Name) + s.log.V(1).Info("can't start/continue 'update': pod is unhealthy", "pod", pod.Name) + continue } // Skip if pod is leader. if pod.ObjectMeta.Labels["role"] == string(utils.Leader) && leaderPod.Name == "" { @@ -342,9 +346,14 @@ func (s *StatefulSetSyncer) updatePod(ctx context.Context) error { if err := s.applyNWait(ctx, &pod); err != nil { return err } + newLeader = fmt.Sprintf("%s.%s.%s", pod.Name, s.GetNameForResource(utils.HeadlessSVC), pod.Namespace) } // There may be a case where Leader does not exist during the update process. - if leaderPod.Name != "" { + if leaderPod.Name != "" && newLeader != "" { + if err := s.XenonExecutor.RaftTryToLeader(newLeader); err != nil { + return err + } + s.log.V(1).Info("leader switch to", "pod", newLeader) // Update the leader. if err := s.applyNWait(ctx, &leaderPod); err != nil { return err