如果主要叢集複製程序失敗,可以切換到次要複製通道。以下程序描述完成此操作所需的步驟。
取得最近一次全域檢查點(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
。