### 23.7.8 使用 NDB Cluster Replication 实现故障转移

[](<>)[](<>)

如果主集群复制过程失败，则可以切换到辅助复制通道。以下过程描述了完成此操作所需的步骤。

1.  [](<>) [](<>)获取最近的全局检查点 (GCP) 的时间。也就是说，您需要从`ndb_apply_status`副本集群上的表，可以使用以下查询找到：

    ```
    mysqlR'> SELECT @latest:=MAX(epoch)
          ->        FROM mysql.ndb_apply_status;
    ```

    在循环复制拓扑中，每个主机上运行一个源和一个副本，当您使用`ndb_log_apply_status=1`, NDB Cluster epoch 被写入副本的二进制日志中。这意味着`ndb_apply_status`表包含此主机上的副本以及充当此主机上运行的复制源服务器的副本的任何其他主机的信息。

    在这种情况下，您需要确定此副本上的最新纪元，以排除此副本的二进制日志中未列出的任何其他副本的任何纪元`IGNORE_SERVER_IDS`的选项[`将复制源更改为`](change-replication-source-to.html)\|[`将主更改为`](change-master-to.html)用于设置此副本的语句。排除此类时期的原因是`mysql.ndb_apply_status`其服务器 ID 在`IGNORE_SERVER_IDS`列表来自[`将复制源更改为`](change-replication-source-to.html)\|`将主更改为`用于准备此副本的源的语句也被认为来自本地服务器，除了那些具有副本自己的服务器 ID 的服务器。您可以将此列表检索为`Replicate_Ignore_Server_Ids`从输出[`显示副本状态`](show-replica-status.html).我们假设您已获得此列表并将其替换为*`ignore_server_ids`*在此处显示的查询中，与之前版本的查询一样，将最大时期选择到一个名为的变量中`@最新的`：

    ```
    mysqlR'> SELECT @latest:=MAX(epoch)
          ->        FROM mysql.ndb_apply_status
          ->        WHERE server_id NOT IN (ignore_server_ids);
    ```

    在某些情况下，使用要包含的服务器 ID 列表可能更简单或更有效（或两者兼而有之）`server_id 输入 *`server_id_list`*`在里面`在哪里`前面查询的条件。

2.  [](<>)使用步骤 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
          -> ORDER BY epoch ASC LIMIT 1;
    ```

    这些是自主复制通道故障以来保存在源上的记录。我们使用了一个用户变量`@最新的`此处表示在步骤1中获得的值。当然，这是不可能的[**mysqld**](mysqld.html)实例直接访问另一个服务器实例上设置的用户变量。这些值必须手动或由应用程序“插入”到第二个查询中。

    重要的

    您必须确保复制副本[**mysqld**](mysqld.html)是从[`--从机跳过错误=ddl_exist_错误`](replication-options-replica.html#option_mysqld_slave-skip-errors)执行前[`开始复制`](start-replica.html)。否则，复制可能会因重复的DDL错误而停止。

3.  现在，可以通过在辅助副本服务器上运行以下查询来同步辅助通道：

    ```
    mysqlR'> CHANGE MASTER TO
          ->     MASTER_LOG_FILE='@file',
          ->     MASTER_LOG_POS=@pos;
    ```

    在MySQL 8.0.23及更高版本中，您还可以使用以下语句：

    ```
    mysqlR'> CHANGE REPLICATION SOURCE TO
          ->     SOURCE_LOG_FILE='@file',
          ->     SOURCE_LOG_POS=@pos;
    ```

    我们再次使用了用户变量（在本例中）`@文件`和`@位置`)表示在步骤2中获得并在步骤3中应用的值；实际上，这些值必须手动插入，或者使用可以访问两台服务器的应用程序插入。

    笔记

    `@文件`是字符串值，例如`“/var/log/mysql/replication source bin。00001'`，因此在SQL或应用程序代码中使用时必须引用。但是`@位置`必须*不*被引用。虽然MySQL通常会尝试将字符串转换为数字，但这种情况是个例外。

4.  现在，您可以通过在辅助复制副本上发出适当的命令，在辅助通道上启动复制[**mysqld**](mysqld.html):

    ```
    mysqlR'> START SLAVE;
    ```

    在MySQL 8.0.22或更高版本中，还可以使用以下语句：

    ```
    mysqlR'> START REPLICA;
    ```

    一旦辅助复制通道处于活动状态，您就可以调查主复制通道的故障并进行修复。执行此操作所需的精确操作取决于主通道故障的原因。

警告

只有当主复制通道出现故障时，才能启动辅助复制通道。同时运行多个复制通道可能会导致在副本上创建不需要的重复记录。

如果故障仅限于一台服务器，理论上应该可以从*`S`*到*`R'`*，或来自*`是的`*到*`R`*.
