為了讓複製能夠對伺服器的意外停止 (有時稱為當機安全) 具有彈性,副本必須能夠在停止之前恢復其狀態。本節說明在複製期間副本意外停止的影響,以及如何設定副本以獲得最佳的復原機會以繼續複製。
當複本(replica)發生預期外的停止後,重新啟動時,複寫 SQL 執行緒必須恢復已執行過的交易的相關資訊。恢復所需的資訊儲存在複本的套用程式(applier)中繼資料儲存庫中。這個儲存庫預設會以名為 mysql.slave_relay_log_info
的 InnoDB
資料表建立。透過使用此具備交易特性的儲存引擎,資訊在重新啟動時始終可以恢復。對套用程式中繼資料儲存庫的更新會與交易一起提交,這表示儲存在該儲存庫中的複本進度資訊,即使在伺服器發生預期外停止的情況下,也始終與已套用至資料庫的內容保持一致。有關套用程式中繼資料儲存庫的更多資訊,請參閱第 19.2.4 節「中繼日誌和複寫中繼資料儲存庫」。
DML 交易以及原子性 DDL 會在套用變更至資料庫的同時,以原子操作的方式,更新複本套用程式中繼資料儲存庫中 mysql.slave_relay_log_info
資料表的複寫位置。在所有其他情況下,包括非完全原子性的 DDL 陳述式,以及不支援原子性 DDL 的豁免儲存引擎,如果伺服器發生預期外的停止,則 mysql.slave_relay_log_info
資料表可能會遺失與複寫資料相關聯的更新。在這種情況下,還原更新是一個手動過程。如需 MySQL 8.4 中原子性 DDL 支援,以及特定陳述式複寫所產生之行為的詳細資訊,請參閱第 15.1.1 節「原子性資料定義陳述式支援」。
複本從預期外的停止中恢復的恢復過程,會根據複本的配置而有所不同。恢復過程的細節會受到選擇的複寫方法、複本是單執行緒還是多執行緒,以及相關系統變數的設定所影響。恢復過程的總體目標是識別在發生預期外停止之前,哪些交易已套用在複本的資料庫上,並擷取和套用複本在發生預期外停止後遺漏的交易。
對於基於 GTID 的複寫,恢復過程需要複本已接收或提交之交易的 GTID。可以使用 GTID 自動定位從來源擷取遺漏的交易,該功能會自動將來源的交易與複本的交易進行比較,並識別遺漏的交易。
對於基於檔案位置的複寫,恢復過程需要精確的複寫 SQL 執行緒(套用程式)位置,以顯示已套用在複本上的最後一筆交易。基於該位置,複寫 I/O 執行緒(接收器)會從來源的二進位日誌中擷取所有應從該點開始套用在複本上的交易。
使用基於 GTID 的複寫可以最輕鬆地配置複寫,使其能夠應對預期外的停止。GTID 自動定位表示複本可以可靠地識別和擷取遺漏的交易,即使在已套用交易的序列中存在間隙也是如此。
以下資訊提供了適用於不同類型複本的設定組合,以確保在複寫的控制範圍內盡可能恢復。
某些超出複寫控制範圍的因素可能會影響複寫恢復過程以及恢復過程後的複寫整體狀態。特別是,影響個別儲存引擎恢復過程的設定,可能會導致在複本發生預期外停止的情況下遺失交易,因此無法用於複寫恢復過程。在下方清單中提到的 innodb_flush_log_at_trx_commit=1
設定,是使用 InnoDB
進行交易之複寫設定的關鍵設定。然而,特定於 InnoDB
或其他儲存引擎的設定,尤其是那些與刷新或同步相關的設定,也可能產生影響。請務必檢查並套用您選擇的儲存引擎所提出的關於崩潰安全設定的建議。
複本上的以下設定組合最能應對預期外的停止
當使用基於 GTID 的複寫時 (
gtid_mode=ON
),請設定SOURCE_AUTO_POSITION=1
,這會啟用連線至來源的 GTID 自動定位,以自動識別和擷取遺漏的交易。此選項是使用CHANGE REPLICATION SOURCE TO
陳述式設定的。如果複本有多個複寫通道,則您需要為每個通道個別設定此選項。如需 GTID 自動定位如何運作的詳細資訊,請參閱第 19.1.3.3 節「GTID 自動定位」。當使用基於檔案位置的複寫時,不使用SOURCE_AUTO_POSITION=1
,而是使用二進位日誌位置或中繼日誌位置來控制複寫的啟動位置。當使用基於 GTID 的複寫時 (
gtid_mode=ON
),請設定GTID_ONLY=1
,這會讓複本在恢復過程中僅使用 GTID,並停止在複寫中繼資料儲存庫中保存二進位日誌和中繼日誌檔案名稱及檔案位置。此選項是使用CHANGE REPLICATION SOURCE TO
陳述式設定的。如果複本有多個複寫通道,則您需要為每個通道個別設定此選項。在GTID_ONLY=1
的情況下,在恢復期間,會忽略檔案位置資訊,並使用 GTID 自動略過來略過已提供的交易,而不是識別正確的檔案位置。只要您使用relay_log_purge
的預設設定來清除中繼日誌,此策略會更有效率,這表示只需要檢查一個中繼日誌檔案。設定
sync_relay_log=1
,這會指示複寫接收器執行緒在每次將接收到的交易寫入磁碟後,將中繼日誌同步到磁碟。這表示複本從來源的二進位日誌讀取到的目前位置記錄(在套用程式中繼資料儲存庫中)永遠不會超前在中繼日誌中儲存的交易記錄。請注意,雖然此設定最安全,但由於涉及的磁碟寫入次數,因此也是最慢的。如果sync_relay_log > 1
,或sync_relay_log=0
(其中同步由作業系統處理),則在複本發生預期外停止的情況下,可能會有已提交但尚未同步到磁碟的交易。如果正在恢復的複本,根據它在中繼日誌中最後同步到磁碟的資訊,嘗試再次擷取和套用交易,而不是略過這些交易,則此類交易可能會導致恢復過程失敗。設定sync_relay_log=1
對於多執行緒複本尤其重要,因為如果無法使用中繼日誌中的資訊填補交易序列中的間隙,則恢復過程會失敗。對於單執行緒複本,只有當套用程式中繼資料儲存庫中沒有相關資訊時,恢復過程才需要使用中繼日誌。設定
innodb_flush_log_at_trx_commit=1
,這會在提交每個交易之前,將InnoDB
日誌同步到磁碟。此設定是預設設定,可確保將InnoDB
資料表和InnoDB
日誌儲存到磁碟,因此不再需要中繼日誌中關於交易的資訊。結合設定sync_relay_log=1
,此設定進一步確保InnoDB
資料表和InnoDB
日誌的內容始終與中繼日誌的內容保持一致,因此在發生預期外停止的情況下,清除中繼日誌檔案不會導致複本的交易記錄中出現無法填補的間隙。設定
relay_log_info_repository = TABLE
,這會將複寫 SQL 執行緒位置儲存在InnoDB
資料表mysql.slave_relay_log_info
中,並在交易提交的同時更新它,以確保記錄始終準確。此設定是預設設定;FILE
已被棄用。系統變數本身也已被棄用,因此請省略它,並允許它採用預設值。如果使用FILE
,則資訊會儲存在資料目錄中的檔案中,該檔案會在套用交易後更新。這會產生與來源失去同步的風險,具體取決於複本停止處理交易的哪個階段,甚至可能導致檔案本身損毀。使用relay_log_info_repository = FILE
時,無法保證恢復。設定
relay_log_recovery = ON
,這會在伺服器啟動後立即啟用自動中繼日誌恢復。此全域變數預設為OFF
,且在執行時為唯讀,但您可以在複本發生預期外停止後,使用複本啟動時的--relay-log-recovery
選項將其設定為ON
。請注意,此設定會忽略現有的中繼日誌檔案,以防它們損毀或不一致。中繼日誌恢復過程會啟動新的中繼日誌檔案,並從來源擷取交易,從套用程式中繼資料儲存庫中記錄的複寫 SQL 執行緒位置開始。先前的中繼日誌檔案會由複本的正常清除機制隨時間移除。
對於多執行緒複本,設定 relay_log_recovery = ON
會自動處理從中繼日誌執行的交易序列中發生的任何不一致和間隙。當使用基於檔案位置的複製時,可能會發生這些間隙。(更多詳細資訊,請參閱第 19.5.1.34 節, “複製和交易不一致”。)中繼日誌恢復過程使用與 START REPLICA UNTIL SQL_AFTER_MTS_GAPS
陳述式相同的方法來處理間隙。當複本達到一致的無間隙狀態時,中繼日誌恢復過程會繼續從來源提取更多的交易,從複製 SQL 執行緒的位置開始。當使用基於 GTID 的複製時,多執行緒複本會先檢查 SOURCE_AUTO_POSITION
是否設定為 ON
,如果是,則會省略計算應該跳過或不跳過的交易的步驟,因此恢復過程不需要舊的中繼日誌。