函数中的 PRIMARY_ELECTION_PATCH_CONSIDERATION 是 0x080017,即 MySQL 8.0.17 。
在 MySQL 8.0.17 中,Group Replication 引入了兼容性策略 。引入兼容性策略的初衷是为了避免集群中出现节点不兼容的情况 。
该函数首先会对 all_members_info 按照版本从小到大排序 。
接着会基于第一个节点的版本(最小版本)确定 lowest_version_end 。
MGR 用 lowest_version_end 标记最低版本的结束点 。只有 lowest_version_end 之前的节点才是候选节点 。
lowest_version_end 的取值逻辑如下:
- 如果最小版本大于等于 MySQL 8.0.17,则会将最小版本之后的第一个节点设置为 lowest_version_end 。
- 如果集群中既有 5.7,又有 8.0,则会将 8.0 的第一个节点设置为 lowest_version_end 。
- 如果最小版本小于 MySQL 8.0.17,且只有一个大版本(major_version),则会取 all_members_info->end() 。此时,所有节点都是候选节点 。
sort_members_for_election最后,我们看看 sort_members_for_election 函数的实现逻辑 。
void sort_members_for_election( std::vector<Group_member_info *> *all_members_info, std::vector<Group_member_info *>::iterator lowest_version_end) { Group_member_info *first_member = *(all_members_info->begin()); // 获取第一个节点的版本,这个节点版本最低 。 Member_version lowest_version = first_member->get_member_version(); // 如果最小版本大于等于 MySQL 5.7.20,则根据节点的权重来排序 。权重越高,在 vector 中的位置越靠前 。 // 注意,这里只会对 [all_members_info->begin(), lowest_version_end) 这个区间内的元素进行排序,不包括 lowest_version_end 。 if (lowest_version >= PRIMARY_ELECTION_MEMBER_WEIGHT_VERSION) std::sort(all_members_info->begin(), lowest_version_end, Group_member_info::comparator_group_member_weight); else // 如果最小版本小于 MySQL 5.7.20,则根据节点的 server_uuid 来排序 。server_uuid 越小,在 vector 中的位置越靠前 。 std::sort(all_members_info->begin(), lowest_version_end, Group_member_info::comparator_group_member_uuid);}
函数中的 PRIMARY_ELECTION_MEMBER_WEIGHT_VERSION 是 0x050720 , 即 MySQL 5.7.20 。如果最小节点的版本大于等于 MySQL 5.7.20,则会基于权重来排序 。权重越高,在 all_members_info 中的位置越靠前 。
如果最小节点的版本小于 MySQL 5.7.20 , 则会基于节点的 server_uuid 来排序 。server_uuid 越小,在 all_members_info 中的位置越靠前 。
注意 , std::sort 中的结束位置是 lowest_version_end,所以 lowest_version_end 这个节点不会参与排序 。
comparator_group_member_weight在基于权重进行排序时,如果两个节点的权重一致 , 还会进一步比较这两个节点的 server_uuid 。
这个逻辑是在 comparator_group_member_weight 中定义的 。
权重一致,节点的 server_uuid 越?。?在 all_members_info 中的位置越靠前 。
bool Group_member_info::comparator_group_member_weight(Group_member_info *m1, Group_member_info *m2) { return m1->has_greater_weight(m2);}bool Group_member_info::has_greater_weight(Group_member_info *other) { MUTEX_LOCK(lock, &update_lock); if (member_weight > other->get_member_weight()) return true; // 如果权重一致,会按照节点的 server_uuid 来排序 。 if (member_weight == other->get_member_weight()) return has_lower_uuid_internal(other); return false;}
案例分析基于上面代码的逻辑,接下来我们分析下 sort_and_get_lowest_version_member_position 函数注释部分列举的四个案例:案例 1:5.7.18, 5.7.18, 5.7.19, 5.7.20, 5.7.21, 8.0.21. 这几个节点中,最小版本号是 5.7.18,小于 MySQL 8.0.17 。所以会比较各个节点的 major_version,因为最后一个节点(8.0.2)的 major_version 和第一个节点不一致,所以会将 8.0.2 作为 lowest_version_end 。此时,除了 8.0.2 , 其它都是候选节点 。
推荐阅读
- 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实现图像分类