每當需要複製的變更發生時,群組都需要達成共識。一般交易是這樣的情況,但群組成員資格變更以及使群組保持一致的某些內部訊息也需要這樣的情況。共識需要大多數群組成員同意給定的決策。當失去大多數群組成員時,群組就無法進展並且會遭到封鎖,因為它無法確保多數或仲裁。
當有多個非自願故障時,可能會失去仲裁,導致大多數伺服器突然從群組中移除。例如,在 5 個伺服器的群組中,如果其中 3 個伺服器同時靜音,則大多數將會受到損害,因此無法達成仲裁。事實上,剩餘的兩個伺服器無法判斷其他 3 個伺服器是否已當機,或是網路分割是否僅隔離了這 2 個伺服器,因此群組無法自動重新設定。
另一方面,如果伺服器自願退出群組,它們會指示群組應重新設定自身。實際上,這表示即將離開的伺服器會告知其他伺服器它即將離開。這表示其他成員可以正確地重新設定群組,保持成員資格的一致性,並重新計算多數。例如,在上述 5 個伺服器的情境中,如果 3 個離開的伺服器逐一警告群組它們即將離開,則成員資格就能夠從 5 個調整為 2 個,同時在這種情況下確保仲裁。
仲裁遺失本身是不良規劃的副作用。針對預期的故障次數規劃群組大小 (無論它們是連續的、同時發生的還是零星的)。
對於單主節點模式的群組,主要節點在網路分割時,可能會有其他成員尚未擁有的交易。如果您正在考慮將主要節點排除在新群組之外,請注意,這類交易可能會遺失。具有額外交易的成員無法重新加入群組,而且嘗試會產生錯誤,並顯示訊息 此成員已執行的交易多於群組中存在的交易。為群組成員設定 group_replication_unreachable_majority_timeout
系統變數,以避免這種情況。
以下章節說明如果系統以群組中的伺服器無法自動達成仲裁的方式分割,該怎麼辦。
replication_group_members
Performance Schema 資料表從此伺服器的觀點顯示目前檢視中每個伺服器的狀態。大多數時候,系統不會發生分割,因此,資料表會顯示在群組中所有伺服器之間一致的資訊。換句話說,目前檢視中的所有成員都同意此資料表上每個伺服器的狀態。但是,如果發生網路分割並且失去仲裁,則資料表會針對無法連線的伺服器顯示狀態 UNREACHABLE
。此資訊是由內建於群組複製的本機故障偵測器匯出。
為了瞭解此類網路分割,以下章節將說明一個情境,其中最初有 5 個伺服器正確地一起工作,然後在只有 2 個伺服器在線上時,群組會發生的變更。此情境如圖所示。
因此,假設有一個包含以下 5 個伺服器的群組
伺服器 s1,成員識別碼為
199b2df7-4aaf-11e6-bb16-28b2bd168d07
伺服器 s2,成員識別碼為
199bb88e-4aaf-11e6-babe-28b2bd168d07
伺服器 s3,成員識別碼為
1999b9fb-4aaf-11e6-bb54-28b2bd168d07
伺服器 s4,成員識別碼為
19ab72fc-4aaf-11e6-bb51-28b2bd168d07
伺服器 s5,成員識別碼為
19b33846-4aaf-11e6-ba81-28b2bd168d07
一開始群組運作良好,而且伺服器彼此之間可以正常通訊。您可以登入 s1 並查看其 replication_group_members
Performance Schema 資料表,藉此驗證這一點。例如
mysql> SELECT MEMBER_ID,MEMBER_STATE, MEMBER_ROLE FROM performance_schema.replication_group_members;
+--------------------------------------+--------------+-------------+
| MEMBER_ID | MEMBER_STATE | MEMBER_ROLE |
+--------------------------------------+--------------+-------------+
| 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | ONLINE | SECONDARY |
| 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | ONLINE | PRIMARY |
| 199bb88e-4aaf-11e6-babe-28b2bd168d07 | ONLINE | SECONDARY |
| 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | ONLINE | SECONDARY |
| 19b33846-4aaf-11e6-ba81-28b2bd168d07 | ONLINE | SECONDARY |
+--------------------------------------+--------------+-------------+
然而,稍後卻發生災難性的故障,伺服器 s3、s4 和 s5 意外停止。幾秒鐘後,再次查看 s1 上的 replication_group_members
表格,顯示它仍然在線上,但其他幾個成員則否。事實上,如下所示,它們被標記為 UNREACHABLE
。此外,系統無法重新配置自身以變更成員資格,因為大多數成員都已遺失。
mysql> SELECT MEMBER_ID,MEMBER_STATE FROM performance_schema.replication_group_members;
+--------------------------------------+--------------+
| MEMBER_ID | MEMBER_STATE |
+--------------------------------------+--------------+
| 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | UNREACHABLE |
| 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | ONLINE |
| 199bb88e-4aaf-11e6-babe-28b2bd168d07 | ONLINE |
| 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | UNREACHABLE |
| 19b33846-4aaf-11e6-ba81-28b2bd168d07 | UNREACHABLE |
+--------------------------------------+--------------+
該表格顯示,s1 現在位於一個沒有外部干預就無法進展的群組中,因為大多數伺服器都無法連線。在這種特殊情況下,需要重設群組成員列表以允許系統繼續運行,這在本節中會說明。或者,您也可以選擇停止 s1 和 s2 上的群組複製 (或完全停止 s1 和 s2),找出 s3、s4 和 s5 發生了什麼問題,然後重新啟動群組複製 (或伺服器)。
群組複製可讓您強制執行特定的組態,以重設群組成員列表。例如,在上述案例中,只有 s1 和 s2 是在線的伺服器,您可以選擇強制執行僅包含 s1 和 s2 的成員組態。這需要檢查有關 s1 和 s2 的一些資訊,然後使用 group_replication_force_members
變數。
假設您回到群組中只剩下 s1 和 s2 的情況。伺服器 s3、s4 和 s5 已意外離開群組。為了讓伺服器 s1 和 s2 繼續運作,您希望強制執行一個僅包含 s1 和 s2 的成員組態。
此程序使用 group_replication_force_members
,應視為最後的補救措施。使用時必須格外小心,且僅用於覆寫仲裁的遺失。如果誤用,可能會造成人為的腦裂情況,或完全封鎖整個系統。
強制執行新的成員組態時,請確保任何將被強制退出群組的伺服器確實已停止運作。在上述情境中,如果 s3、s4 和 s5 並非真的無法連線,而是處於線上狀態,它們可能已形成自己的功能性分割區(它們是 5 個中的 3 個,因此它們擁有大多數)。在這種情況下,強制使用 s1 和 s2 的群組成員列表可能會造成人為的腦裂情況。因此,在強制執行新的成員組態之前,務必確認要排除的伺服器確實已關閉,如果沒有,請在繼續之前將其關閉。
對於單主節點模式的群組,主要節點在網路分割時,可能會有其他成員尚未擁有的交易。如果您正在考慮將主要節點排除在新群組之外,請注意,這類交易可能會遺失。具有額外交易的成員無法重新加入群組,而且嘗試會產生錯誤,並顯示訊息 此成員已執行的交易多於群組中存在的交易。為群組成員設定 group_replication_unreachable_majority_timeout
系統變數,以避免這種情況。
回想一下,系統已遭封鎖,目前的組態如下(由 s1 上的本機故障偵測器感知)
mysql> SELECT MEMBER_ID,MEMBER_STATE FROM performance_schema.replication_group_members;
+--------------------------------------+--------------+
| MEMBER_ID | MEMBER_STATE |
+--------------------------------------+--------------+
| 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | UNREACHABLE |
| 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | ONLINE |
| 199bb88e-4aaf-11e6-babe-28b2bd168d07 | ONLINE |
| 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | UNREACHABLE |
| 19b33846-4aaf-11e6-ba81-28b2bd168d07 | UNREACHABLE |
+--------------------------------------+--------------+
首先要做的是檢查 s1 和 s2 的本機位址(群組通訊識別碼)。登入 s1 和 s2 並依照下列方式取得該資訊。
mysql> SELECT @@group_replication_local_address;
一旦您知道 s1 (127.0.0.1:10000
) 和 s2 (127.0.0.1:10001
) 的群組通訊位址,您就可以在其中一個伺服器上使用它來注入新的成員組態,從而覆寫已失去仲裁的現有組態。若要在 s1 上執行此操作
mysql> SET GLOBAL group_replication_force_members="127.0.0.1:10000,127.0.0.1:10001";
這會透過強制執行不同的組態來解除群組封鎖。請查看 s1 和 s2 上的 replication_group_members
,以驗證變更後的群組成員資格。首先在 s1 上。
mysql> SELECT MEMBER_ID,MEMBER_STATE FROM performance_schema.replication_group_members;
+--------------------------------------+--------------+
| MEMBER_ID | MEMBER_STATE |
+--------------------------------------+--------------+
| b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | ONLINE |
| b60907e7-4ab6-11e6-afb7-28b2bd168d07 | ONLINE |
+--------------------------------------+--------------+
然後在 s2 上。
mysql> SELECT * FROM performance_schema.replication_group_members;
+--------------------------------------+--------------+
| MEMBER_ID | MEMBER_STATE |
+--------------------------------------+--------------+
| b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | ONLINE |
| b60907e7-4ab6-11e6-afb7-28b2bd168d07 | ONLINE |
+--------------------------------------+--------------+
在使用 group_replication_force_members
系統變數成功強制執行新的群組成員資格並解除群組封鎖後,請確保您清除該系統變數。group_replication_force_members
必須為空,才能發出 START GROUP_REPLICATION
陳述式。