如果主要叢集複製程序失敗,可以切換到次要複製通道。以下程序說明完成此操作所需的步驟。
取得最近一次全域檢查點 (GCP) 的時間。也就是說,您需要從副本叢集上的
ndb_apply_status
資料表中決定最近的 epoch,可以使用以下查詢找到:mysqlR'> SELECT @latest:=MAX(epoch) -> FROM mysql.ndb_apply_status;
在循環複製拓撲中,每個主機上都執行來源和副本,當您使用
ndb_log_apply_status=1
時,NDB 叢集 epoch 會寫入副本的二進位日誌中。這表示ndb_apply_status
資料表包含此主機上副本的資訊,以及任何其他充當此主機上執行之複製來源伺服器副本的主機的資訊。在這種情況下,您需要決定此副本上的最新 epoch,排除此副本二進位日誌中任何其他副本的 epoch,這些副本未列在用於設定此副本的
CHANGE REPLICATION SOURCE TO
語句的IGNORE_SERVER_IDS
選項中。排除此類 epoch 的原因在於,mysql.ndb_apply_status
資料表中伺服器 ID 在用於準備此副本來源的CHANGE REPLICATION SOURCE TO
語句的IGNORE_SERVER_IDS
清單中具有相符項的列,除了具有副本自身伺服器 ID 的列之外,也被視為來自本機伺服器。您可以從SHOW REPLICA STATUS
的輸出中將此清單擷取為Replicate_Ignore_Server_Ids
。我們假設您已取得此清單,並且在以下顯示的查詢中將其替換為ignore_server_ids
,此查詢與先前的查詢版本一樣,會將最大 epoch 選取至名為@latest
的變數中mysqlR'> SELECT @latest:=MAX(epoch) -> FROM mysql.ndb_apply_status -> WHERE server_id NOT IN (ignore_server_ids);
在某些情況下,使用要包含的伺服器 ID 清單,以及在上述查詢的
WHERE
條件中使用server_id IN
可能會更簡單或更有效率 (或兩者兼具)。server_id_list
使用從步驟 1 所示查詢中取得的資訊,從來源叢集上的
ndb_binlog_index
資料表中取得對應的記錄。您可以使用以下查詢,從來源上的
ndb_binlog_index
資料表中取得所需的記錄mysqlS'> SELECT -> @file:=SUBSTRING_INDEX(next_file, '/', -1), -> @pos:=next_position -> FROM mysql.ndb_binlog_index -> WHERE epoch = @latest;
這些是自主要複製通道失敗以來,儲存在來源上的記錄。我們在此處使用使用者變數
@latest
來表示在步驟 1 中取得的值。當然,一個 mysqld 執行個體無法直接存取在另一個伺服器執行個體上設定的使用者變數。這些值必須手動或透過應用程式 「插入」 到第二個查詢中。重要事項您必須確保在執行
START REPLICA
之前,使用--replica-skip-errors=ddl_exist_errors
啟動副本 mysqld。否則,複製可能會因為重複的 DDL 錯誤而停止。現在,可以透過在次要副本伺服器上執行以下查詢來同步次要通道
mysqlR'> CHANGE REPLICATION SOURCE TO -> SOURCE_LOG_FILE='@file', -> SOURCE_LOG_POS=@pos;
我們再次使用使用者變數 (在此案例中為
@file
和@pos
) 來表示在步驟 2 中取得的值,並在步驟 3 中應用;實際上,這些值必須手動插入,或使用可以存取所涉及兩個伺服器的應用程式來插入。注意@file
是字串值,例如'/var/log/mysql/replication-source-bin.00001'
,因此在 SQL 或應用程式程式碼中使用時必須加上引號。但是,@pos
所代表的值不得加上引號。雖然 MySQL 通常會嘗試將字串轉換為數字,但此案例是例外情況。您現在可以在次要副本 mysqld 上發出適當的命令,以啟動次要通道上的複製。
mysqlR'> START REPLICA;
次要複製通道啟動後,您可以調查主要通道的失敗原因並進行修復。執行此操作所需的確切動作取決於主要通道失敗的原因。
僅當主要複製通道失敗時,才應啟動次要複製通道。同時執行多個複製通道可能會導致在副本上建立不必要的重複記錄。
如果失敗僅限於單一伺服器,理論上應該可以從 S
複製到 R'
,或從 S'
複製到 R
。