如果複製因為複製交易中的事件問題而停止,您可以透過跳過複本上失敗的交易來恢復複製。在跳過交易之前,請確保複製 I/O(接收器)執行緒以及 SQL(應用程式)執行緒都已停止。
首先,您需要找出導致錯誤的複寫事件。錯誤的詳細資訊以及最後成功套用的交易會記錄在效能結構描述表 replication_applier_status_by_worker
中。您可以使用 mysqlbinlog 來擷取並顯示錯誤發生前後記錄的事件。如需執行此操作的說明,請參閱第 9.5 節「時間點(增量)復原」。或者,您也可以在副本上發出 SHOW RELAYLOG EVENTS
,或在來源上發出 SHOW BINLOG EVENTS
。
在跳過交易並重新啟動副本之前,請檢查以下幾點:
導致複寫停止的交易是否來自未知或不受信任的來源?如果是,請調查原因,以防有任何安全考量指出不應重新啟動副本。
導致複寫停止的交易是否需要在副本上套用?如果是,請進行適當的更正並重新套用交易,或手動調整副本上的資料。
導致複寫停止的交易是否需要在來源上套用?如果不是,請在最初發生交易的伺服器上手動復原交易。
若要跳過交易,請視情況選擇下列其中一種方法:
當使用 GTID 時(
gtid_mode
為ON
),請參閱第 19.1.7.3.1 節「使用 GTID 跳過交易」。當未使用 GTID 或正在逐步引入 GTID 時(
gtid_mode
為OFF
、OFF_PERMISSIVE
或ON_PERMISSIVE
),請參閱第 19.1.7.3.2 節「不使用 GTID 跳過交易」。如果您已使用
CHANGE REPLICATION SOURCE TO
陳述式的ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS
選項,在複寫通道上啟用 GTID 指派,請參閱第 19.1.7.3.2 節「不使用 GTID 跳過交易」。在複寫通道上使用ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS
與為該通道引入基於 GTID 的複寫不同,且您無法對這些通道使用基於 GTID 的複寫的交易跳過方法。
若要在跳過交易後重新啟動複寫,請發出 START REPLICA
,如果副本是多來源副本,則使用 FOR CHANNEL
子句。
當使用 GTID 時(gtid_mode
為 ON
),即使篩選掉交易內容,已提交交易的 GTID 也會保留在副本上。此功能可防止副本在使用 GTID 自動定位重新連線到來源時,擷取先前篩選的交易。它也可以用來跳過副本上的交易,方法是提交一個空交易來取代失敗的交易。
當您已使用 CHANGE REPLICATION SOURCE TO
陳述式的 ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS
選項,在複寫通道上啟用 GTID 指派時,此交易跳過方法不適用。
如果失敗的交易在工作執行緒中產生錯誤,您可以直接從效能結構描述表 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 會被保留,但交易本身會被清除二進位記錄檔所移除。
若要在未使用 GTID 或正在逐步引入 GTID 時(gtid_mode
為 OFF
、OFF_PERMISSIVE
或 ON_PERMISSIVE
)跳過失敗的交易,您可以發出 SET GLOBAL sql_replica_skip_counter
來跳過指定數量的事件。或者,您也可以發出 CHANGE REPLICATION SOURCE TO
陳述式,以將來源二進位記錄位置往前移動,跳過一個或多個事件。
當您已使用 CHANGE REPLICATION SOURCE TO
陳述式的 ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS
選項,在複寫通道上啟用 GTID 指派時,這些方法也適用。
當您使用這些方法時,務必了解您不一定會跳過完整的交易,如同先前描述的基於 GTID 的方法一樣。這些非基於 GTID 的方法並不知道交易,而是對事件進行操作。二進位記錄會組織為稱為事件群組的序列,而每個事件群組都由一系列事件組成。
對於交易式資料表,事件群組對應於交易。
對於非交易式資料表,事件群組對應於單一 SQL 陳述式。
雖然單一交易有可能包含對交易式和非交易式資料表的變更,但對於此類交易的支援已遭到棄用,您應預期它會在未來版本的 MySQL 中移除。請參閱第 19.5.1.36 節「複寫和交易」。如需此棄用的一些原因,請參閱第 19.1.3.7 節「使用 GTID 進行複寫的限制」。
當您使用 SET GLOBAL sql_replica_skip_counter
陳述式來跳過事件,且產生的位置位於事件群組的中間時,副本會繼續跳過事件,直到它到達群組的結尾。然後,執行會從下一個事件群組開始。CHANGE REPLICATION SOURCE TO
陳述式沒有此功能,因此您必須小心識別正確的位置,以便在事件群組的開頭重新啟動複寫。然而,使用 CHANGE REPLICATION SOURCE TO
表示您不必像使用 SET GLOBAL sql_replica_skip_counter
一樣計算需要跳過的事件,而是可以只指定要重新啟動的位置。
當您評估失敗的交易是否有任何其他適當的動作(如先前所述的安全考量)時,請計算需要跳過的事件數量。一個事件通常對應於二進位記錄中的一個 SQL 陳述式,但請注意,使用 AUTO_INCREMENT
或 LAST_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
子句。請確保您命名了正確的通道,否則會在錯誤的通道上跳過事件。
當您評估失敗的交易是否有任何其他適當的動作(如先前所述的安全考量)時,請識別來源二進位記錄中代表重新啟動複寫的合適位置的座標(檔案和位置)。這可以是導致問題的事件之後的事件群組的開頭,或下一個交易的開頭。複寫 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;
如果副本是多來源副本,您必須使用 FOR CHANNEL
子句,在 CHANGE REPLICATION SOURCE TO
陳述式上命名適當的通道。
如果 SOURCE_AUTO_POSITION
為 1
,或如果複寫 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;