文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手冊頁面 (TGZ) - 258.5Kb
手冊頁面 (Zip) - 365.5Kb
資訊 (Gzip) - 4.0Mb
資訊 (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  跳過交易

19.1.7.3 跳過交易

如果複製因複製交易中的事件問題而停止,您可以透過跳過副本上失敗的交易來繼續複製。在跳過交易之前,請確保複製 I/O (接收器) 執行緒以及 SQL (套用程式) 執行緒都已停止。

首先,您需要識別導致錯誤的複製事件。錯誤的詳細資訊以及最後成功套用的交易會記錄在效能架構(Performance Schema)的 replication_applier_status_by_worker 表格中。您可以使用 mysqlbinlog 來檢索和顯示錯誤發生前後記錄的事件。關於如何執行此操作的說明,請參閱第 9.5 節,「時間點(增量)復原」。或者,您可以在副本上執行 SHOW RELAYLOG EVENTS,或在來源上執行 SHOW BINLOG EVENTS

在跳過交易並重新啟動副本之前,請檢查以下幾點:

  • 停止複製的交易是否來自不明或不信任的來源?如果是,請調查原因,以防有任何安全考量表明不應重新啟動副本。

  • 停止複製的交易是否需要在副本上套用?如果是,請進行適當的更正並重新套用交易,或手動在副本上協調資料。

  • 停止複製的交易是否需要在來源上套用?如果不是,請在最初發生交易的伺服器上手動撤銷該交易。

若要跳過交易,請選擇下列其中一種適當的方法:

若要在跳過交易後重新啟動複製,請執行 START REPLICA,如果副本是多來源副本,請使用 FOR CHANNEL 子句。

19.1.7.3.1 使用 GTID 跳過交易

當使用 GTID 時(gtid_modeON),即使交易內容被過濾掉,已提交交易的 GTID 也會保存在副本上。此功能可防止副本在使用 GTID 自動定位重新連線至來源時,擷取先前過濾的交易。它也可以用來跳過副本上的交易,方法是提交一個空交易來取代失敗的交易。

如果您使用 CHANGE REPLICATION SOURCE TO 陳述式的 ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS 選項,在複製通道上啟用了 GTID 指派,則此跳過交易的方法不適用。

如果失敗的交易在工作執行緒中產生錯誤,您可以直接從效能架構(Performance Schema)的 replication_applier_status_by_worker 表格中的 APPLYING_TRANSACTION 欄位取得其 GTID。若要查看交易的內容,請在副本上執行 SHOW RELAYLOG EVENTS,或在來源上執行 SHOW BINLOG EVENTS,並在輸出中搜尋以該 GTID 開頭的交易。

當您評估失敗的交易是否有任何其他適當的動作(如先前所述的安全考量)時,若要跳過該交易,請在副本上提交一個與失敗交易具有相同 GTID 的空交易。例如:

SET GTID_NEXT='aaa-bbb-ccc-ddd:N';
BEGIN;
COMMIT;
SET GTID_NEXT='AUTOMATIC';

副本上存在此空交易表示,當您執行 START REPLICA 陳述式以重新啟動複製時,副本會使用自動跳過功能來忽略失敗的交易,因為它看到具有該 GTID 的交易已套用。如果副本是多來源副本,則在提交空交易時不需要指定通道名稱,但在執行 START REPLICA 時則需要指定通道名稱。

請注意,如果在此副本上使用二進位日誌記錄,則如果副本在未來成為來源或主要副本,則空交易會進入複製串流。如果您需要避免這種可能性,請考慮清除和清除副本的二進位日誌,如本範例所示:

FLUSH LOGS;
PURGE BINARY LOGS TO 'binlog.000146';

空交易的 GTID 會被保留,但交易本身會透過清除二進位日誌檔案來移除。

19.1.7.3.2 不使用 GTID 跳過交易

若要在未使用 GTID 或正在逐步導入 GTID 時(gtid_modeOFFOFF_PERMISSIVEON_PERMISSIVE)跳過失敗的交易,您可以透過執行 SET GLOBAL sql_replica_skip_counter 來跳過指定數量的事件。或者,您可以執行 CHANGE REPLICATION SOURCE TO 陳述式來跳過一個或多個事件,將來源二進位日誌位置向前移動。

當您使用 CHANGE REPLICATION SOURCE TO 陳述式的 ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS 選項,在複製通道上啟用 GTID 指派時,這些方法也適用。

當您使用這些方法時,請務必了解,您不一定會跳過完整的交易,這與先前所述的基於 GTID 的方法的情況始終不同。這些非基於 GTID 的方法不會將交易視為交易,而是對事件進行操作。二進位日誌會組織成稱為事件群組的序列,每個事件群組都由一系列事件組成。

  • 對於交易式表格,事件群組對應於一個交易。

  • 對於非交易式表格,事件群組對應於單個 SQL 陳述式。

單個交易可能包含對交易式和非交易式表格的變更。

當您使用 SET GLOBAL sql_replica_skip_counter 陳述式來跳過事件,並且產生的位置位於事件群組的中間時,副本會繼續跳過事件,直到到達群組的末尾。然後,執行會從下一個事件群組開始。CHANGE REPLICATION SOURCE TO 陳述式沒有此功能,因此您必須小心識別正確的位置,以便在事件群組的開頭重新啟動複製。然而,使用 CHANGE REPLICATION SOURCE TO 表示您不必像使用 SET GLOBAL sql_replica_skip_counter 那樣計算需要跳過的事件,而是可以只指定重新啟動的位置。

19.1.7.3.2.1 使用 SET GLOBAL sql_replica_skip_counter 跳過交易

當您評估失敗的交易是否有任何其他適當的動作(如先前所述的安全考量)時,請計算您需要跳過的事件數量。一個事件通常對應於二進位日誌中的一個 SQL 陳述式,但請注意,使用 AUTO_INCREMENTLAST_INSERT_ID() 的陳述式在二進位日誌中算作兩個事件。當使用二進位日誌交易壓縮時,壓縮的交易酬載(Transaction_payload_event)算作單一計數器值,因此其中的所有事件都會作為一個單位跳過。

如果您要跳過完整的交易,您可以將事件計數到交易結束,或者您可以只跳過相關的事件群組。請記住,使用 SET GLOBAL sql_replica_skip_counter 時,副本會繼續跳到事件群組的末尾。請確保您沒有跳過太遠,進入下一個事件群組或交易,以至於它也被跳過。

請依以下方式執行 SET 陳述式,其中 N 是要從來源跳過的事件數:

SET GLOBAL sql_replica_skip_counter = N

如果已設定 gtid_mode=ON,或複製 I/O(接收器)和 SQL(應用程式)執行緒正在執行,則無法執行此陳述式。

SET GLOBAL sql_replica_skip_counter 陳述式不會立即生效。當您在此 SET 陳述式之後,下次發出 START REPLICA 陳述式時,系統變數 sql_replica_skip_counter 的新值才會被套用,並且會略過事件。該 START REPLICA 陳述式也會自動將系統變數的值設回 0。如果複本是多來源複本,當您發出該 START REPLICA 陳述式時,則必須使用 FOR CHANNEL 子句。請務必指定正確的通道,否則會在錯誤的通道上略過事件。

19.1.7.3.2.2 使用 CHANGE REPLICATION SOURCE TO 略過交易

當您已如先前所述評估失敗的交易是否有任何其他適當的動作(例如安全性考量)時,請找出來源二進位日誌中代表適合重新啟動複製的位置的座標(檔案和位置)。這可以是導致問題的事件之後的事件群組的開始,或下一個交易的開始。下次執行緒啟動時,複製 I/O(接收器)執行緒會從來源的這些座標開始讀取,略過失敗的事件。請務必準確識別位置,因為此陳述式不考量事件群組。

請如下發出 CHANGE REPLICATION SOURCE TO 陳述式,其中 source_log_name 是包含重新啟動位置的二進位日誌檔案,而 source_log_pos 是代表二進位日誌檔案中重新啟動位置的數字

CHANGE REPLICATION SOURCE TO SOURCE_LOG_FILE='source_log_name', SOURCE_LOG_POS=source_log_pos;

如果複本是多來源複本,您必須在 CHANGE REPLICATION SOURCE TO 陳述式上使用 FOR CHANNEL 子句來命名適當的通道。

如果 SOURCE_AUTO_POSITION1,或複製 I/O(接收器)和 SQL(套用器)執行緒正在執行,則無法發出此陳述式。如果您需要在 SOURCE_AUTO_POSITION=1 時使用此方法來略過交易,您可以在發出陳述式時將設定變更為 SOURCE_AUTO_POSITION=0,然後再將其變更回原狀。例如

CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION=0, SOURCE_LOG_FILE='binlog.000145', SOURCE_LOG_POS=235;
CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION=1;