從中繼日誌執行的交易順序中的不一致可能會根據您的複製組態而發生。本節說明如何避免不一致並解決它們造成的任何問題。
可能存在以下類型的不一致
半套用交易。更新非交易式資料表的交易已套用部分但非全部變更。
間隙。當給定交易的排序序列時,序列中較晚的交易在序列中較早的其他交易之前套用時,就會出現外部化交易集中的間隙。只有在使用多執行緒複本時才會出現間隙。
若要避免在多執行緒複本上發生間隙,請設定
replica_preserve_commit_order=ON
。這是預設值,因為所有複本預設都是多執行緒的。在複本上設定
replica_preserve_commit_order=ON
不需要二進制日誌記錄和複本更新日誌記錄,而且如果需要,可以停用。設定
replica_preserve_commit_order=ON
要求replica_parallel_type
設定為LOGICAL_CLOCK
。在 MySQL 9.0 中,這是預設值。在某些特定情況下,如
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 執行緒,當使用多執行緒副本時為協調器執行緒)。這會中止進行中的交易,並可能留下間隙和半應用交易。應用執行緒中發生錯誤。這可能會留下間隙。如果錯誤發生在混合交易中,則該交易為半應用。當使用多執行緒副本時,沒有收到錯誤的工作執行緒會完成其佇列,因此可能需要一些時間才能停止所有執行緒。
當使用多執行緒副本時,使用
STOP REPLICA
。在發出STOP REPLICA
後,副本會等待填補任何間隙,然後更新Exec_master_log_pos
。這可確保它永遠不會留下間隙或來源二進制日誌位置延遲,除非適用上述任何情況,換句話說,在STOP REPLICA
完成之前,發生錯誤,或者另一個執行緒發出KILL
,或者伺服器重新啟動。在這些情況下,STOP REPLICA
會成功返回。如果中繼日誌中的最後一個交易僅接收了一半,且多執行緒副本的協調器執行緒已開始將該交易排程到工作執行緒,則
STOP REPLICA
會等待最多 60 秒以接收該交易。在此逾時後,協調器會放棄並中止該交易。如果該交易是混合交易,則可能會留下未完成的一半。當進行中的交易僅更新交易式表格時,
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 副本上不允許這樣做。