根據您的複製組態,可能會發生從中繼日誌執行的交易順序不一致的情況。本節說明如何避免不一致並解決它們引起的任何問題。
可能存在以下類型的不一致
部分應用交易。更新非交易式資料表的交易已套用部分變更,但未套用全部變更。
間隙。當給定一個已排序的交易序列時,序列中較後的交易在序列中較早的其他交易之前套用時,會出現外部化交易集中的間隙。僅在使用多執行緒副本時才會出現間隙。
若要避免間隙發生在多執行緒副本上,請設定
replica_preserve_commit_order=ON
。這是預設設定,因為所有副本預設都是多執行緒。在副本上不需要二進位日誌記錄和副本更新日誌記錄即可設定
replica_preserve_commit_order=ON
,如果需要,可以停用。設定
replica_preserve_commit_order=ON
需要將replica_parallel_type
設定為LOGICAL_CLOCK
。在 MySQL 8.4 中,這是預設設定。在某些特定情況下,如
replica_preserve_commit_order
的描述中所列,設定replica_preserve_commit_order=ON
無法在副本上保留提交順序,因此在這些情況下,從副本的中繼日誌執行的交易順序中可能仍然會出現間隙。設定
replica_preserve_commit_order=ON
不會阻止來源二進位日誌位置延遲。來源二進位日誌位置延遲。即使沒有間隙,也可能已套用
Exec_master_log_pos
之後的交易。也就是說,已套用直到N
點的所有交易,且未套用N
之後的任何交易,但Exec_master_log_pos
的值小於N
。在這種情況下,Exec_master_log_pos
是已套用交易的「低水位標記」,並且會落後於最近套用交易的位置。這僅可能發生在多執行緒副本上。啟用replica_preserve_commit_order
不會阻止來源二進位日誌位置延遲。
以下情境與部分應用交易、間隙和來源二進位日誌位置延遲的存在相關
當複製執行緒正在執行時,可能會出現間隙和部分應用交易。
mysqld 關閉。乾淨和不乾淨的關機都會中止正在進行的交易,並可能留下間隙和部分應用交易。
中止複製執行緒的
KILL
(當使用單執行緒副本時為 SQL 執行緒,當使用多執行緒副本時為協調器執行緒)。這會中止正在進行的交易,並可能留下間隙和半套用的交易。套用程式執行緒發生錯誤。這可能會留下間隙。如果錯誤發生在混合交易中,則該交易會被半套用。當使用多執行緒副本時,未收到錯誤的 worker 會完成其佇列,因此可能需要一些時間才能停止所有執行緒。
當使用多執行緒副本時,使用
STOP REPLICA
。發出STOP REPLICA
後,副本會等待任何間隙被填補,然後更新Exec_master_log_pos
。這確保它永遠不會留下間隙或來源二進制日誌位置的延遲,除非套用上述任何情況,換句話說,在STOP REPLICA
完成之前,發生錯誤,或另一個執行緒發出KILL
,或伺服器重新啟動。在這些情況下,STOP REPLICA
會成功返回。如果中繼日誌中的最後一個交易僅接收到一半,且多執行緒副本的協調器執行緒已開始將該交易排程給 worker,則
STOP REPLICA
最多會等待 60 秒以接收該交易。在此逾時後,協調器會放棄並中止該交易。如果該交易是混合的,則可能會留下半完成的狀態。當正在進行的交易僅更新事務性資料表時使用
STOP REPLICA
,在這種情況下,它會回滾且STOP REPLICA
會立即停止。如果正在進行的交易是混合的,則STOP REPLICA
最多會等待 60 秒以完成該交易。在此逾時後,它會中止該交易,因此可能會留下半完成的狀態。
系統變數 rpl_stop_replica_timeout
的全域設定與停止複製執行緒的過程無關。它只會使發出 STOP REPLICA
的用戶端返回到用戶端,但複製執行緒會繼續嘗試停止。
如果複製通道存在間隙,則會產生以下後果
副本資料庫處於可能從未在來源上存在過的狀態。
SHOW REPLICA STATUS
中的Exec_master_log_pos
欄位只是一個「低水位標記」。換句話說,出現在該位置之前的交易保證已提交,但該位置之後的交易可能已提交或未提交。該通道的
CHANGE REPLICATION SOURCE TO
語句會失敗並出現錯誤,除非套用程式執行緒正在運行且該語句僅設定接收器選項。如果使用
--relay-log-recovery
啟動 mysqld,則不會對該通道執行恢復,並會列印警告。如果將 mysqldump 與
--dump-replica
一起使用,它不會記錄間隙的存在;因此它會列印CHANGE REPLICATION SOURCE TO
,其中RELAY_LOG_POS
設定為Exec_master_log_pos
中的「低水位標記」位置。在另一台伺服器上套用轉儲並啟動複製執行緒後,該位置之後出現的交易會再次被複製。請注意,如果啟用了 GTID,這不會造成任何損害 (但是,在這種情況下,不建議使用
--dump-replica
)。
如果複製通道具有來源二進制日誌位置延遲但沒有間隙,則適用上述案例 2 至 5,但不適用案例 1。
來源二進制日誌位置資訊以二進制格式儲存在內部資料表 mysql.slave_worker_info
中。START REPLICA [SQL_THREAD]
始終會查詢此資訊,以便僅套用正確的交易。即使在 START REPLICA
之前,replica_parallel_workers
已變更為 0,甚至即使 START REPLICA
與 UNTIL
一起使用,情況仍然如此。START REPLICA UNTIL SQL_AFTER_MTS_GAPS
只會套用填補間隙所需的交易。如果 START REPLICA
與 UNTIL
子句一起使用,該子句告訴它在消耗所有間隙之前停止,則它會留下剩餘的間隙。
RESET REPLICA
會移除中繼日誌並重設複製位置。因此,在具有間隙的多執行緒副本上發出 RESET REPLICA
表示副本會遺失有關間隙的任何資訊,而不會更正間隙。在這種情況下,如果使用基於二進制日誌位置的複製,則恢復過程會失敗。
當使用基於 GTID 的複製 (GTID_MODE=ON
) 且使用 CHANGE REPLICATION SOURCE TO
語句為複製通道設定 SOURCE_AUTO_POSITION
時,恢復過程不需要舊的中繼日誌。相反,副本可以使用 GTID 自動定位來計算它與來源相比缺少哪些交易。當使用基於 GTID 的複製時,會完全略過用於基於二進制日誌位置的複製以解決多執行緒副本上間隙的過程。當略過此過程時,START REPLICA UNTIL SQL_AFTER_MTS_GAPS
語句的行為會有所不同,並且不會嘗試檢查交易序列中是否存在間隙。您也可以發出 CHANGE REPLICATION SOURCE TO
語句,這些語句在存在間隙的非 GTID 副本上是不允許的。