從源碼分析 MGR 的新主選舉算法( 二 )

這個函數里面,比較關鍵的地方有三個:

  1. 調用 sort_and_get_lowest_version_member_position 。
    這個函數會基于 member_version (節點版本)選擇候選節點 。
    只有候選節點才有資格被選為主節點。
  2. 調用 sort_members_for_election 。
    這個函數會基于節點權重和 server_uuid,對候選節點進行排序 。
  3. 基于排序后的候選節點選擇 Primary 節點 。
    因為候選節點是從頭開始遍歷,所以基本上,只要第一個節點是 ONLINE 狀態,就會把這個節點作為 Primary 節點 。
sort_and_get_lowest_version_member_position接下來我們看看 sort_and_get_lowest_version_member_position 函數的實現邏輯 。
sort_and_get_lowest_version_member_position(    std::vector<Group_member_info *> *all_members_info) {  std::vector<Group_member_info *>::iterator it;  // 按照版本對 all_members_info 從小到大排序  std::sort(all_members_info->begin(), all_members_info->end(),            Group_member_info::comparator_group_member_version);  // std::vector::end 會返回一個迭代器,該迭代器引用 vector (向量容器)中的末尾元素 。  // 注意,這個元素指向的是 vector 最后一個元素的下一個位置,不是最后一個元素 。  std::vector<Group_member_info *>::iterator lowest_version_end =      all_members_info->end();  // 獲取排序后的第一個節點 , 這個節點版本最低 。  it = all_members_info->begin();  Group_member_info *first_member = *it;  // 獲取第一個節點的 major_version  // 對于 MySQL 5.7,major_version 是 5;對于 MySQL 8.0,major_version 是 8  uint32 lowest_major_version =      first_member->get_member_version().get_major_version();    /* to avoid read compatibility issue leader should be picked only from lowest     version members so save position where member version differs.     From 8.0.17 patch version will be considered during version comparison.     set lowest_version_end when major version changes     eg: for a list: 5.7.18, 5.7.18, 5.7.19, 5.7.20, 5.7.21, 8.0.2         the members to be considered for election will be:            5.7.18, 5.7.18, 5.7.19, 5.7.20, 5.7.21         and server_uuid based algorithm will be used to elect primary     eg: for a list: 5.7.20, 5.7.21, 8.0.2, 8.0.2         the members to be considered for election will be:            5.7.20, 5.7.21         and member weight based algorithm will be used to elect primary     eg: for a list: 8.0.17, 8.0.18, 8.0.19         the members to be considered for election will be:            8.0.17     eg: for a list: 8.0.13, 8.0.17, 8.0.18         the members to be considered for election will be:            8.0.13, 8.0.17, 8.0.18         and member weight based algorithm will be used to elect primary  */    // 遍歷剩下的節點,注意 it 是從 all_members_info->begin() + 1 開始的  for (it = all_members_info->begin() + 1; it != all_members_info->end();       it++) {   // 如果第一個節點的版本號大于 MySQL 8.0.17,且節點的版本號不等于第一個節點的版本號 , 則將該節點賦值給 lowest_version_end,并退出循環 。    if (first_member->get_member_version() >=            PRIMARY_ELECTION_PATCH_CONSIDERATION &&        (first_member->get_member_version() != (*it)->get_member_version())) {      lowest_version_end = it;      break;    }    // 如果節點的 major_version 不等于第一個節點的 major_version,則將該節點賦值給 lowest_version_end,并退出循環 。    if (lowest_major_version !=        (*it)->get_member_version().get_major_version()) {      lowest_version_end = it;      break;    }  }  return lowest_version_end;}

推薦閱讀