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;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Object Detection 手把手教你使用LabVIEW OpenCV dnn实现物体识别含源码
- MatrixOne从入门到实战04——MatrixOne的连接和建表
- MatrixOne从入门到实践08——SSB性能测试
- 从零开始学Graph Database:什么是图
- 咸鱼之王龙鱼义从怎么搭配
- 记一次 .NET 某工控视觉软件 非托管泄漏分析
- 三星zFlip3值得买吗_三星zFlip3优缺点分析
- Jupyter,Matplotlib,Pandas 【机器学习】利用 Python 进行数据分析的环境配置 Windows
- 传奇祖玛阁怎么从6层下到5层(传奇怎么从祖玛阁去七层大厅)
- 含源码 手把手教你使用LabVIEW OpenCV dnn实现图像分类