文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  設定交易一致性保證

20.5.3.2 設定交易一致性保證

雖然交易同步點章節說明了從概念上來說,您可以選擇兩個同步點:讀取時或寫入時,但這些術語是一種簡化,而群組複製中使用的術語是:交易執行之前之後。如本節所示,一致性層級可能會對群組處理的唯讀 (RO) 和讀寫 (RW) 交易產生不同的影響。

以下列表顯示您可以使用 group_replication_consistency 變數在群組複製中設定的可能一致性層級,依交易一致性保證遞增的順序排列

  • EVENTUAL

    RO 和 RW 交易在執行之前都不會等待先前的交易套用。這是新增 group_replication_consistency 變數之前群組複製的行為。RW 交易不會等待其他成員套用交易。這表示交易可能會在其他成員之前在一個成員上外部化。這也表示在主要伺服器容錯移轉的情況下,新的主要伺服器可以在套用先前的主要伺服器交易之前,接受新的 RO 和 RW 交易。RO 交易可能會產生過時的值,RW 交易可能會因衝突而導致回溯。

  • BEFORE_ON_PRIMARY_FAILOVER

    具有新選出,且正在套用來自舊主要伺服器之待辦項目的主要伺服器的新 RO 或 RW 交易會被保留 (不套用),直到任何待辦項目已套用。這可確保在發生主要伺服器容錯移轉 (無論是有意或無意) 時,用戶端始終會在主要伺服器上看到最新值。這保證了一致性,但也表示用戶端必須能夠處理正在套用待辦項目時的延遲。通常此延遲應該很小,但它確實取決於待辦項目的規模。

  • BEFORE

    RW 交易會等待所有先前的交易完成,然後再套用。RO 交易會等待所有先前的交易完成,然後再執行。這可確保此交易只會透過影響交易的延遲時間來讀取最新值。這可減少每次 RW 交易同步處理的額外負荷,方法是確保僅在 RO 交易上使用同步處理。此一致性層級也包括 BEFORE_ON_PRIMARY_FAILOVER 所提供的一致性保證。

  • AFTER

    RW 交易會等待,直到其變更已套用到所有其他成員。此值對 RO 交易沒有影響。此模式可確保當交易在本機成員上提交時,任何後續交易都會在任何群組成員上讀取寫入的值或較新的值。將此模式與主要用於 RO 操作的群組搭配使用,以確保套用的 RW 交易在提交後會套用到所有位置。您的應用程式可以使用此模式,以確保後續讀取會擷取包含最新寫入的最新資料。這可減少每次 RO 交易同步處理的額外負荷,方法是確保僅在 RW 交易上使用同步處理。此一致性層級也包括 BEFORE_ON_PRIMARY_FAILOVER 所提供的一致性保證。

  • BEFORE_AND_AFTER

    RW 交易會等待 1) 所有先前的交易完成,然後再套用,以及 2) 直到其變更已套用到其他成員。RO 交易會等待所有先前的交易完成,然後再執行。此一致性層級也包括 BEFORE_ON_PRIMARY_FAILOVER 所提供的一致性保證。

BEFOREBEFORE_AND_AFTER 一致性層級都可以在 RO 和 RW 交易上使用。AFTER 一致性層級對 RO 交易沒有影響,因為它們不會產生變更。

如何選擇一致性層級

不同的 一致性層級為 DBA (他們可以使用這些層級來設定其基礎架構) 和開發人員 (他們可以使用最適合其應用程式需求的一致性層級) 都提供了彈性。下列案例顯示如何根據您使用群組的方式來選擇一致性保證層級

  • 案例 1:您想要平衡讀取負載,而不用擔心讀取過時的讀取,您的群組寫入操作明顯少於群組讀取操作。在這種情況下,您應該選擇 AFTER

  • 情境 2 您有一個大量寫入的資料集,並且希望偶爾進行讀取,而無需擔心讀取到過時的資料。在這種情況下,您應該選擇 BEFORE

  • 情境 3 您希望工作負載中的特定交易始終從群組讀取最新的資料,以便在更新敏感資料(例如檔案憑證或類似資料)時,確保讀取始終讀取最新的值。在這種情況下,您應該選擇 BEFORE

  • 情境 4 您有一個主要為唯讀 (RO) 資料的群組,您希望讀寫 (RW) 交易在提交後應用到所有地方,以便後續的讀取操作是在包含您最新寫入的最新資料上進行,並且您不必在每個 RO 交易上都進行同步,而只需在 RW 交易上進行同步。在這種情況下,您應該選擇 AFTER

  • 情境 5 您有一個主要為唯讀資料的群組,您希望讀寫 (RW) 交易始終從群組讀取最新的資料,並在提交後應用到所有地方,以便後續的讀取操作是在包含您最新寫入的最新資料上進行,並且您不必在每個唯讀 (RO) 交易上都進行同步,而只需在 RW 交易上進行同步。在這種情況下,您應該選擇 BEFORE_AND_AFTER

您可以自由選擇強制執行一致性層級的範圍。這一點很重要,因為如果將一致性層級設定為全域範圍,可能會對群組效能產生負面影響。因此,您可以透過在不同的範圍使用 group_replication_consistency 系統變數來設定群組的一致性層級。

若要在目前的工作階段強制執行一致性層級,請使用工作階段範圍。

> SET @@SESSION.group_replication_consistency= 'BEFORE';

若要在所有工作階段強制執行一致性層級,請使用全域範圍。

> SET @@GLOBAL.group_replication_consistency= 'BEFORE';

在特定工作階段設定一致性層級的可能性使您可以利用以下情境:

  • 情境 6 某個系統處理多個不需要強一致性層級的指令,但其中一種指令確實需要強一致性:管理文件的存取權限。在這種情境中,系統會變更存取權限,並希望確保所有用戶端都看到正確的權限。您只需要在這些指令上 SET @@SESSION.group_replication_consistency= ‘AFTER’,並讓其他指令在全域範圍設定的 EVENTUAL 下執行。

  • 情境 7 與情境 6 中描述的相同系統,每天都需要執行一些分析處理的指令,因此它需要始終讀取最新的資料。為達到此目的,您只需要在該特定指令上 SET @@SESSION.group_replication_consistency= ‘BEFORE’

總之,您不需要以特定的一致性層級執行所有交易,特別是只有某些交易實際上需要時。

請注意,所有讀寫交易在群組複寫中都是完全排序的,因此即使您將目前工作階段的一致性層級設定為 AFTER,此交易也會等待直到其變更應用於所有成員,這表示等待此交易以及可能在次要節點佇列中的所有先前交易。實際上,一致性層級 AFTER 會等待所有項目,直到包含此交易。

一致性層級的影響

對一致性層級進行分類的另一種方式是根據對群組的影響,也就是一致性層級對其他成員造成的影響。

除了在交易串流上進行排序之外,BEFORE 一致性層級只會影響本機成員。也就是說,它不需要與其他成員協調,也不會對其交易產生影響。換句話說,BEFORE 只會影響使用它的交易。

AFTERBEFORE_AND_AFTER 一致性層級確實會對其他成員上執行的並行交易產生副作用。如果具有 EVENTUAL 一致性層級的交易在執行具有 AFTERBEFORE_AND_AFTER 的交易時開始,則這些一致性層級會讓其他成員的交易等待。其他成員會等待,直到 AFTER 交易在該成員上提交,即使其他成員的交易具有 EVENTUAL 一致性層級也一樣。換句話說,AFTERBEFORE_AND_AFTER 會影響所有 ONLINE 群組成員。

為了進一步說明這一點,請想像一個包含 3 個成員的群組,M1、M2 和 M3。在成員 M1 上,用戶端發出

> SET @@SESSION.group_replication_consistency= AFTER;
> BEGIN;
> INSERT INTO t1 VALUES (1);
> COMMIT;

然後,在套用上述交易時,在成員 M2 上,用戶端發出

> SET SESSION group_replication_consistency= EVENTUAL;

在這種情況下,即使第二個交易的一致性層級為 EVENTUAL,因為它是在第一個交易已經在 M2 上進入提交階段時開始執行的,所以第二個交易必須等待第一個交易完成提交,才能執行。

您只能在 ONLINE 成員上使用一致性層級 BEFOREAFTERBEFORE_AND_AFTER,嘗試在其他狀態的成員上使用它們會導致工作階段錯誤。

一致性層級不是 EVENTUAL 的交易會將執行保持到達到逾時為止,逾時值由 wait_timeout 值設定,預設值為 8 小時。如果達到逾時,則會擲回 ER_GR_HOLD_WAIT_TIMEOUT 錯誤。

一致性對主要節點選取的影響

本節說明群組的一致性層級如何影響已選出新主要節點的單一主要節點群組。此類群組會自動偵測失敗,並調整作用中成員的檢視,換句話說,即成員資格設定。此外,如果以單一主要節點模式部署群組,則每當群組的成員資格變更時,就會執行檢查以偵測群組中是否仍有主要成員。如果沒有,則會從次要成員清單中選取新的主要成員。通常,這稱為次要節點升級。

鑑於系統會自動偵測失敗並重新設定本身的事實,使用者也可能會預期,一旦發生升級,新主要節點的資料狀態與舊主要節點完全相同。換句話說,使用者可能會預期,一旦他的應用程式容錯移轉到新的主要節點,就不會發生讀取舊資料或寫入舊資料記錄的可能性,即使是暫時的也一樣。

當流量控制在群組上啟動並適當調整時,在升級後立即從新選出的主要節點暫時讀取過時資料的可能性很小,因為不應該有待處理的工作,或者如果有,也應該很小。此外,您可能會有 Proxy 或中介層,會在升級後管理應用程式對主要節點的存取,並在該層級強制執行一致性準則。您可以使用 group_replication_consistency 變數指定新主要節點在升級後的行為,該變數會控制新選出的主要節點是否會封鎖讀寫,直到完全套用待處理工作為止。如果 group_replication_consistency 變數在新選出的主要節點上設定為 BEFORE_ON_PRIMARY_FAILOVER,而該主要節點有待套用的待處理工作,並且在它仍在套用待處理工作時對新的主要節點發出交易,則傳入的交易會遭到封鎖,直到完全套用待處理工作為止。因此,會防止下列異常情況

  • 唯讀和讀寫交易沒有過時的讀取。這可防止過時的讀取由新的主要節點外部化到應用程式。

  • 由於與仍處於待套用佇列中且已複寫的讀寫交易發生寫入衝突,因此讀寫交易不會發生虛假的復原。

  • 讀寫交易沒有讀取偏差,例如

    > BEGIN;
    > SELECT x FROM t1; -- x=1 because x=2 is in the backlog;
    > INSERT x INTO t2;
    > COMMIT;

    此查詢不應導致衝突,但會寫入過時的值。

總之,當 group_replication_consistency 設定為 BEFORE_ON_PRIMARY_FAILOVER 時,您會選擇優先考慮一致性而非可用性,因為每當選出新的主要節點時,讀寫都會暫停。這是您在設定群組時必須考慮的權衡。還應該記住,如果流量控制正常運作,則待處理工作應該會是最小的。請注意,較高的一致性層級 BEFOREAFTERBEFORE_AND_AFTER 也包含 BEFORE_ON_PRIMARY_FAILOVER 提供的保證一致性。

為了確保群組提供相同的一致性層級,而不管哪個成員升級為主要節點,群組的所有成員都應該將 BEFORE_ON_PRIMARY_FAILOVER(或更高的一致性層級)保存在其設定中。例如,在每個成員上發出

> SET PERSIST group_replication_consistency='BEFORE_ON_PRIMARY_FAILOVER';

這可確保所有成員的行為方式相同,並且在成員重新啟動後,設定會被保存下來。

交易無法永久保持,如果保持的時間超過 wait_timeout,則會傳回 ER_GR_HOLD_WAIT_TIMEOUT 錯誤。

一致性規則下允許的查詢

雖然在使用 BEFORE_ON_PRIMARY_FAILOVER 一致性層級時會暫停所有寫入,但並非所有讀取都會遭到封鎖,以確保您在升級後套用待處理工作時仍可檢查伺服器。這對於偵錯、監視、可觀測性和疑難排解很有用。允許某些不會修改資料的查詢,例如下列各項

  • SHOW 陳述式:這僅限於不依賴資料,而僅依賴狀態和設定的陳述式,如下所列

  • SET 陳述式

  • DO 不使用資料表或可載入函式的陳述式

  • EMPTY 陳述式

  • USE 陳述式

  • 針對 performance_schemasys 資料庫使用 SELECT 陳述式

  • 針對 infoschema 資料庫中的 PROCESSLIST 資料表使用 SELECT 陳述式

  • SELECT 不使用資料表或可載入函式的陳述式

  • STOP GROUP_REPLICATION 陳述式

  • SHUTDOWN 陳述式

  • RESET PERSIST 陳述式

允許的 SHOW 陳述式有 SHOW VARIABLESSHOW PROCESSLISTSHOW STATUSSHOW ENGINE INNODB LOGSSHOW ENGINE INNODB STATUSSHOW ENGINE INNODB MUTEXSHOW BINARY LOG STATUSSHOW REPLICA STATUSSHOW CHARACTER SETSHOW COLLATIONSHOW BINARY LOGSSHOW OPEN TABLESSHOW REPLICASSHOW BINLOG EVENTSSHOW WARNINGSSHOW ERRORSSHOW ENGINESSHOW PRIVILEGESSHOW PROCEDURE STATUSSHOW FUNCTION STATUSSHOW PLUGINSSHOW EVENTSSHOW PROFILESHOW PROFILESSHOW RELAYLOG EVENTS