MGR 的新主选举算法 , 在节点版本一致的情况下 , 其实也挺简单的 。
首先比较权重 , 权重越高 , 选为新主的优先级越高 。
如果权重一致 , 则会进一步比较节点的 server_uuid 。server_uuid 越小 , 选为新主的优先级越高 。
所以 , 在节点版本一致的情况下 , 会选择权重最高 , server_uuid 最小的节点作为新的主节点 。
节点的权重由 group_replication_member_weight 决定 , 该参数是 MySQL 5.7.20 引入的 , 可设置 0 到 100 之间的任意整数值 , 默认是 50 。
但如果集群节点版本不一致 , 实际的选举算法就没这么简单了 。
下面 , 我们结合源码具体分析下 。
代码实现逻辑新主选举算法主要会涉及三个函数:
- pick_primary_member
- sort_and_get_lowest_version_member_position
- sort_members_for_election
其中 , pick_primary_member 是主函数 , 它会基于其它两个函数的结果选择 Primary 节点 。
下面 , 我们从 pick_primary_member 出发 , 看看这三个函数的具体实现逻辑 。
pick_primary_member
bool Primary_election_handler::pick_primary_member( std::string &primary_uuid, std::vector<Group_member_info *> *all_members_info) { DBUG_TRACE; bool am_i_leaving = true;#ifndef NDEBUG int n = 0;#endif Group_member_info *the_primary = nullptr; std::vector<Group_member_info *>::iterator it; std::vector<Group_member_info *>::iterator lowest_version_end; // 基于 member_version 选择候选节点 。 lowest_version_end = sort_and_get_lowest_version_member_position(all_members_info); // 基于节点权重和 server_uuid 对候选节点进行排序 。 sort_members_for_election(all_members_info, lowest_version_end); // 遍历所有节点 , 判断 Primary 节点是否已定义 。 for (it = all_members_info->begin(); it != all_members_info->end(); it++) {#ifndef NDEBUG assert(n <= 1);#endif Group_member_info *member = *it; // 如果当前节点是单主模式且遍历的节点中有 Primary 节点 , 则将该节点赋值给 the_primary if (local_member_info->in_primary_mode() && the_primary == nullptr && member->get_role() == Group_member_info::MEMBER_ROLE_PRIMARY) { the_primary = member;#ifndef NDEBUG n++;#endif } // 检查当前节点的状态是否为 OFFLINE 。 if (!member->get_uuid().compare(local_member_info->get_uuid())) { am_i_leaving = member->get_recovery_status() == Group_member_info::MEMBER_OFFLINE; } } // 如果当前节点的状态不是 OFFLINE 且 the_primary 还是为空 , 则选择一个 Primary 节点 if (!am_i_leaving) { if (the_primary == nullptr) { // 因为循环的结束条件是 it != lowest_version_end 且 the_primary 为空 , 所以基本上会将候选节点中的第一个节点作为 Primary 节点 。 for (it = all_members_info->begin(); it != lowest_version_end && the_primary == nullptr; it++) { Group_member_info *member_info = *it; assert(member_info); if (member_info && member_info->get_recovery_status() == Group_member_info::MEMBER_ONLINE) the_primary = member_info; } } } if (the_primary == nullptr) return true; primary_uuid.assign(the_primary->get_uuid()); return false;}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2023年2月14日上学好吗 2023年2月14日上学黄道吉日
- 2023年2月14日开学典礼吉日一览表 2023年2月14日开学典礼黄道吉日
- 2023年农历正月廿四拜师学艺吉日 2023年2月14日是拜师学艺的黄道吉日吗
- 2023年2月14日清扫房屋行吗 2023年2月14日清扫房屋黄道吉日
- 2023年2月14日堵蚁穴好吗 2023年2月14日堵蚁穴好不好
- 2023年2月14日适合取蜂蜜吗 2023年2月14日取蜂蜜吉日一览表
- 2023年2月14日是遇见贵人吉日吗 2023年农历正月廿四宜遇见贵人吗
- 2023年2月14日剃头好吗 2023年2月14日是剃头吉日吗
- 2023年2月14日理头黄道吉日 2023年2月14日理头好不好
- 2023年2月14日是剪指甲的黄道吉日吗 2023年2月14日剪指甲黄道吉日