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


2. 最小版本號 5.7.18 小于 MySQL 5.7.20,所以 5.7.18, 5.7.18, 5.7.19, 5.7.20, 5.7.21 這幾個節點會根據 server_uuid 進行排序 。注意,lowest_version_end 的節點不會參與排序 。
3. 選擇 server_uuid 最小的節點作為 Primary 節點 。
案例 2:5.7.20, 5.7.21, 8.0.2, 8.0.21. 同案例 1 一樣 , 會將 8.0.2 作為 lowest_version_end 。此時,候選節點只有 5.7.20 和 5.7.21 。
2. 最小版本號 5.7.20 等于 MySQL 5.7.20,所以,5.7.20, 5.7.21 這兩個節點會根據節點的權重進行排序 。如果權重一致,則會基于 server_uuid 進行進一步的排序 。
3. 選擇權重最高,server_uuid 最小的節點作為 Primary 節點 。
案例 3:8.0.17, 8.0.18, 8.0.191. 最小版本號是 MySQL 8.0.17 , 等于 MySQL 8.0.17,所以會判斷其它節點的版本號是否與第一個節點相同 。不相同,則會將該節點的版本號賦值給 lowest_version_end 。所以,會將 8.0.18 作為 lowest_version_end 。此時,候選節點只有 8.0.17 。
2. 選擇 8.0.17 這個節點作為 Primary 節點 。
案例 4:8.0.13, 8.0.17, 8.0.181. 最小版本號是 MySQL 8.0.13 , 小于 MySQL 8.0.17,而且各個節點的 major_version 一致,所以最后返回的 lowest_version_end 實際上是 all_members_info->end() 。此時,這三個節點都是候選節點 。
2. MySQL 8.0.13 大于 MySQL 5.7.20,所以這三個節點會根據權重進行排序 。如果權重一致,則會基于 server_uuid 進行進一步的排序 。
3. 選擇權重最高,server_uuid 最小的節點作為 Primary 節點 。
手動選主從 MySQL 8.0.13 開始,我們可以通過以下兩個函數手動選擇新的主節點:

  • group_replication_set_as_primary(server_uuid) :切換單主模式下的 Primary 節點 。
  • group_replication_switch_to_single_primary_mode([server_uuid]) :將多主模式切換為單主模式 ??赏ㄟ^ server_uuid 指定單主模式下的 Primary 節點 。
在使用這兩個參數時,注意,指定的 server_uuid 必須屬于候選節點 。
另外 , 這兩個函數是 MySQL 8.0.13 引入的 , 所以,如果集群中存在 MySQL 8.0.13 之前的節點,執行時會報錯 。
mysql> select group_replication_set_as_primary('5470a304-3bfa-11ed-8bee-83f233272a5d');ERROR 3910 (HY000): The function 'group_replication_set_as_primary' failed. The group has a member with a version that does not support group coordinated operations.總結結合代碼和上面四個案例的分析,最后我們總結下 MGR 的新主選舉算法:
1. 如果集群中存在 MySQL 5.7 的節點,則會將 MySQL 5.7 的節點作為候選節點 。
2. 如果集群節點的版本都是 MySQL 8.0,這里需要區分兩種情況:
  • 如果最小版本小于 MySQL 8.0.17,則所有的節點都可作為候選節點 。
  • 如果最小版本大于等于 MySQL 8.0.17,則只有最小版本的節點會作為候選節點 。
3. 在候選節點的基礎上,會進一步根據候選節點的權重和 server_uuid 選擇 Primary 節點 。具體來說 , 
  • 如果候選節點中存在 MySQL 5.7.20 之前版本的節點,則會選擇 server_uuid 最小的節點作為 Primary 節點 。
  • 如果候選節點都大于等于 MySQL 5.7.20,則會選擇權重最高,server_uuid 最小的節點作為 Primary 節點 。
【從源碼分析 MGR 的新主選舉算法】

推薦閱讀