

# 为 Amazon RDS for MySQL 配置多源复制
<a name="mysql-multi-source-replication"></a>

通过多源复制，您可以将 Amazon RDS for MySQL 数据库实例设置为一个副本，该副本接收来自多个 RDS for MySQL 源数据库实例的二进制日志事件。运行以下引擎版本的 RDS for MySQL 数据库实例支持多源复制：
+ 所有 MySQL 8.4 版本
+ 8.0.35 及更高的次要版本
+ 5.7.44 及更高的次要版本

有关 MySQL 多源复制的信息，请参阅 MySQL 文档中的 [MySQL Multi-Source Replication](https://dev.mysql.com/doc/refman/8.0/en/replication-multi-source.html)。MySQL 文档包含有关此功能的详细信息，而本主题则介绍如何在 RDS for MySQL 数据库实例上配置和管理多源复制通道。

## 多源复制的使用案例
<a name="mysql-multi-source-replication-benefits"></a>

以下情况很适合在 RDS for MySQL 上使用多源复制：
+ 需要将不同数据库实例上的多个分片合并或组合成单个分片的应用程序。
+ 需要根据从多个来源整合的数据生成报告的应用程序。
+ 要求为分布在多个 RDS for MySQL 数据库实例中的数据创建长期合并备份。

## 多源复制的先决条件
<a name="mysql-multi-source-replication-prerequisites"></a>

在配置多源复制之前，请完成以下先决条件。
+ 确保每个源 RDS for MySQL 数据库实例都启用了自动备份。启用自动备份可启用二进制日志记录。要了解如何启用自动备份，请参阅[启用自动备份](USER_WorkingWithAutomatedBackups.Enabling.md)。
+ 为避免复制错误，建议您阻止对源数据库实例的写入操作。为此，您可以在附加到 RDS for MySQL 源数据库实例的自定义参数组中将 `read-only` 参数设置为 `ON`。您可以使用 AWS 管理控制台或 AWS CLI 来创建新的自定义参数组或修改现有的自定义参数组。有关更多信息，请参阅[在 Amazon RDS 中创建数据库参数组](USER_WorkingWithParamGroups.Creating.md)和[在 Amazon RDS 中修改数据库参数组中的参数](USER_WorkingWithParamGroups.Modifying.md)。
+ 对于每个源数据库实例，将实例的 IP 地址添加到多源数据库实例的 Amazon Virtual Private Cloud（VPC）安全组中。要确定源数据库实例的 IP 地址，可以运行命令 `dig RDS Endpoint`。在与目标多源数据库实例相同的 Amazon EC2 实例中运行命令。
+ 对于每个源数据库实例，使用客户端连接到数据库实例，并创建一个具有复制所需权限的数据库用户，如下例所示。

  ```
  CREATE USER 'repl_user' IDENTIFIED BY 'password';
  GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user';
  ```
**注意**  
从 MySQL 8.4 开始，`REPLICATION SLAVE` 权限已弃用并替换为 `REPLICATION REPLICA`。对于 8.4 及更高版本，请改用以下语法：  

  ```
  CREATE USER 'repl_user' IDENTIFIED BY 'password';
  GRANT REPLICATION CLIENT, REPLICATION REPLICA ON *.* TO 'repl_user';
  ```

## 在 RDS for MySQL 数据库实例上配置多源复制通道
<a name="mysql-multi-source-replication-configuring-channels"></a>

配置多源复制通道与配置单源复制类似。对于多源复制，首先在源实例上开启二进制日志记录。然后，将数据从源导入到多源副本。然后，您可以使用二进制日志坐标或使用 GTID 自动定位从每个源开始复制。

要将 RDS for MySQL 数据库实例配置为两个或更多 RDS for MySQL 数据库实例的多源副本，请执行以下步骤。

**Topics**
+ [步骤 1：将数据从源数据库实例导入到多源副本](#mysql-multi-source-replication-import)
+ [步骤 2：开始从源数据库实例复制到多源副本](#mysql-multi-source-replication-setting-up-start-replication-other)

### 步骤 1：将数据从源数据库实例导入到多源副本
<a name="mysql-multi-source-replication-import"></a>

在每个源数据库实例上执行以下步骤。

在将数据从源导入到多源副本之前，请通过运行 `SHOW MASTER STATUS` 命令来确定当前的二进制日志文件和位置。请记下这些详细信息，以便在下一个步骤中使用。在此示例输出中，文件为 `mysql-bin-changelog.000031`，位置为 `107`。

**注意**  
从 MySQL 8.4 开始，`SHOW MASTER STATUS` 命令已弃用并替换为 `SHOW BINARY LOG STATUS`。对于 8.4 及更高版本，请改用 `SHOW BINARY LOG STATUS`。

```
File                        Position   
-----------------------------------
mysql-bin-changelog.000031      107   
-----------------------------------
```

现在，使用 `mysqldump` 将数据库从源数据库实例复制到多源副本，如下例所示。

```
mysqldump --databases database_name \
 --single-transaction \
 --compress \
 --order-by-primary \
 -u RDS_user_name \
 -p RDS_password \
 --host=RDS Endpoint | mysql \
 --host=RDS Endpoint \
 --port=3306 \
 -u RDS_user_name \
-p RDS_password
```

复制数据库后，可以在源数据库实例上将只读参数设置为 `OFF`。

### 步骤 2：开始从源数据库实例复制到多源副本
<a name="mysql-multi-source-replication-setting-up-start-replication-other"></a>

对于每个源数据库实例，使用管理用户凭证连接到实例，然后运行以下两个存储过程。这些存储过程在通道上配置复制并开始复制。此示例会使用上一步的示例输出中的二进制日志文件名和位置。

```
CALL mysql.rds_set_external_source_for_channel('mysourcehost.example.com', 3306, 'repl_user', 'password', 'mysql-bin-changelog.000031', 107, 1, 'channel_1');
CALL mysql.rds_start_replication_for_channel('channel_1');
```

有关使用这些存储过程和其它存储过程来设置和管理复制通道的更多信息，请参阅[管理多源复制](mysql-stored-proc-multi-source-replication.md)。

## 将筛选条件与多源复制结合使用
<a name="mysql-multi-source-replication-filters"></a>

您可以使用复制筛选条件来指定在多源副本中使用哪些数据库和表进行复制。复制筛选条件可以将数据库和表包含在复制之中或排除在复制之外。有关复制筛选条件的更多信息，请参阅[使用 MySQL 配置复制筛选条件](USER_MySQL.Replication.ReadReplicas.ReplicationFilters.md)。

使用多源复制，您可以全局或在通道级配置复制筛选条件。通道级筛选仅适用于运行 8.0 或 8.4 版本的受支持数据库实例。以下各示例介绍如何全局或在通道级配置筛选条件。

请注意多源复制中筛选的以下要求和行为：
+ 通道名称前后需要使用反引号（``）。
+ 如果您在参数组中更改复制筛选条件，则会对所有带有更新的通道重启多源副本的 `sql_thread` 以动态应用更改。如果更新涉及全局筛选条件，则所有处于运行状态的复制通道都将重启。
+ 所有全局筛选条件都在任何通道特定的筛选条件之前应用。
+ 如果在全局和通道级应用筛选条件，则仅应用通道级筛选条件。例如，如果筛选条件为 `replicate_ignore_db="db1,`channel_22`:db2"`，则 `replicate_ignore_db`（设置为 `db1`）将应用于除 `channel_22` 之外的所有通道，并且 `channel_22` 仅忽略来自 `db2` 的更改。

示例 1：设置全局筛选条件

在以下示例中，将 `temp_data` 数据库排除在每个通道的复制之外。

对于 Linux、macOS 或 Unix：

```
aws rds modify-db-parameter-group \
--db-parameter-group-name myparametergroup \
--parameters "ParameterName=replicate-ignore-db,ParameterValue='temp_data',ApplyMethod=immediate"
```

示例 2：设置通道级筛选条件

在以下示例中，来自 `sample22` 数据库的更改仅包含在通道 `channel_22` 中。同样，来自 `sample99` 数据库的更改仅包含在通道 `channel_99` 中。

对于 Linux、macOS 或 Unix：

```
aws rds modify-db-parameter-group \
--db-parameter-group-name myparametergroup \
--parameters "ParameterName=replicate-do-db,ParameterValue='\`channel_22\`:sample22,\`channel_99\`:sample99',ApplyMethod=immediate"
```

## 监控多源复制通道
<a name="mysql-multi-source-replication-monitoring"></a>

您可以使用以下方法监控多源副本中的各个通道：
+ 要监控所有通道或特定通道的状态，请连接到多源副本并运行 `SHOW REPLICA STATUS` 或 `SHOW REPLICA STATUS FOR CHANNEL 'channel_name'` 命令。有关更多信息，请参阅 MySQL 文档中的[检查复制状态](https://dev.mysql.com/doc/refman/8.0/en/replication-administration-status.html)。
+ 要在启动、停止或移除复制通道时接收通知，请使用 RDS 事件通知。有关更多信息，请参阅 [使用 Amazon RDS 事件通知](USER_Events.md)。
+ 要监控特定通道的滞后，请检查它的 `ReplicationChannelLag` 指标。此指标的数据点的期间为 60 秒（1分钟），可使用 15 天。要查找通道的复制通道滞后，请使用实例标识符和复制通道名称。要在此滞后超过特定阈值时收到通知，您可以设置 CloudWatch 警报。有关更多信息，请参阅 [使用 Amazon CloudWatch 监控 Amazon RDS 指标](monitoring-cloudwatch.md)。

## 多源复制的注意事项和最佳实践
<a name="mysql-multi-source-replication-considerations"></a>

在 RDS for MySQL 上使用多源复制之前，请查看以下注意事项和最佳实践：
+ 确保配置为多源副本的数据库实例具有足够的资源，例如吞吐量、内存、CPU 和 IOPS，以处理来自多个源实例的工作负载。
+ 定期监控多源副本的资源利用率，调整存储或实例配置，以便在不造成资源紧张的情况下处理工作负载。
+ 通过将系统变量 `replica_parallel_workers` 设置为大于 `0` 的值，可以在多源副本上配置多线程复制。在这种情况下，分配给每个通道的线程数就是此变量的值，再加上一个用于管理应用程序线程的协调器线程。
+ 适当配置复制筛选条件以避免冲突。要将整个数据库复制到副本上的另一个数据库，可以使用 `--replicate-rewrite-db` 选项。例如，您可以将数据库 A 中的所有表复制到副本实例上的数据库 B。当所有源实例都使用相同的架构命名约定时，这种方法会很有用。有关 `--replicate-rewrite-db` 选项的信息，请参阅 MySQL 文档中的 [Replica Server Options and Variables](https://dev.mysql.com/doc/refman/8.0/en/replication-options-replica.html)。
+ 为避免复制错误，请避免写入副本。建议您在多源副本上启用 `read_only` 参数以阻止写入操作。这样做有助于消除由于写入操作冲突而导致的复制问题。
+ 要提高在多源副本上执行的读取操作（例如排序和高负载联接）的性能，请考虑使用 RDS 优化型读取功能。此功能有助于处理依赖大型临时表或排序文件的查询。有关更多信息，请参阅 [使用 Amazon RDS 优化读取提高 RDS for MySQL 的查询性能](rds-optimized-reads.md)。
+ 为了显著减少复制滞后并提高多源副本的性能，请考虑启用优化型写入功能。有关更多信息，请参阅 [使用适用于 MySQL 的 RDS 优化型写入功能提高写入性能](rds-optimized-writes.md)。
+ 一次对一个通道执行管理操作（例如更改配置），并避免从多个连接对多个通道执行更改。这些做法可能会导致复制操作发生冲突。例如，通过多个连接同时执行 `rds_skip_repl_error_for_channel` 和 `rds_start_replication_for_channel` 过程可能会导致跳过与预期不同的通道上的事件。
+ 您可以在多源复制实例上启用备份，并将数据从该实例导出到 Amazon S3 存储桶，以便长期存储。但是，还要在各个源实例上配置具有适当保留期的备份，这一点很重要。有关将快照数据导出到 Amazon S3 的信息，请参阅[将 Amazon RDS 的数据库快照数据导出到 Amazon S3](USER_ExportSnapshot.md)。
+ 要在多源副本上分配读取工作负载，您可以从多源副本创建只读副本。您可以根据应用程序的要求将这些只读副本放在不同的 AWS 区域中。有关只读副本的更多信息，请参阅 [使用 MySQL 只读副本](USER_MySQL.Replication.ReadReplicas.md)。

## RDS for MySQL 上多源复制的限制
<a name="mysql-multi-source-replication-limitations"></a>

以下限制适用于 RDS for MySQL 上的多源复制：
+ 目前，RDS for MySQL 支持为多源副本配置最多 15 个通道。
+ 只读副本实例不能配置为多源副本。
+ 要在运行引擎版本 5.7 的 RDS for MySQL 上配置多源复制，必须在副本实例上启用 Performance Schema。对于运行 8.0 或 8.4 版引擎的 RDS for MySQL，可选择是否启用 Performance Schema。
+ 对于运行 5.7 版引擎的 RDS for MySQL，复制筛选条件适用于所有复制通道。对于运行 8.0 或 8.4 版引擎的 RDS for MySQL，可以配置适用于所有复制通道或单个通道的筛选条件。
+ 还原 RDS 快照或执行时间点恢复（PITR）并不会还原多源副本通道配置。
+ 创建多源副本的只读副本时，它只会复制多源实例中的数据。它不会还原任何通道配置。
+ MySQL 不支持为每个通道设置不同数量的并行工作线程。每个通道根据 `replica_parallel_workers` 值获得相同数量的并行工作线程。

如果您的多源复制目标为多可用区数据库集群，则以下其它限制适用：
+ 在对源 RDS for MySQL 实例进行任何写入之前，必须为该实例配置通道。
+ 每个源 RDS for MySQL 实例都必须启用基于 GTID 的复制。
+ 数据库集群上的失效转移事件会移除多源复制配置。还原该配置需要重复配置步骤。