

# 在 Amazon RDS 中使用 MySQL 复制
<a name="USER_MySQL.Replication"></a>

一般使用只读副本配置 Amazon RDS 数据库实例之间的复制。有关只读副本的一般信息，请参阅[使用数据库实例只读副本](USER_ReadRepl.md)。有关使用 Amazon RDS for MySQL 上的只读副本的特定信息，请参阅 [使用 MySQL 只读副本](USER_MySQL.Replication.ReadReplicas.md)。

您可以使用全局事务标识符 (GTID) 与 RDS for MySQL 之间进行复制。有关更多信息，请参阅 [使用基于 GTID 的复制](mysql-replication-gtid.md)。

还可以设置 RDS for MySQL 数据库实例与 Amazon RDS 外部的 MariaDB 或 MySQL 实例之间的复制。有关配置外部源复制的信息，请参阅[配置与外部源实例之间的二进制日志文件位置复制](MySQL.Procedural.Importing.External.Repl.md)。

对于其中任何复制选项，您可以使用基于行的复制、基于语句的复制或混合复制。基于行的复制仅复制因 SQL 语句而导致更改的行。基于语句的复制将复制整个 SQL 语句。混合复制尽可能使用基于语句的复制，但当运行对于基于语句的复制不安全的 SQL 语句时切换到基于行的复制。在大多数情况下，建议使用混合复制。数据库实例的二进制日志格式确定复制是基于行、基于语句还是混合的。有关设置二进制日志格式的信息，请参阅[为单可用区数据库配置 RDS for MySQL 二进制日志记录](USER_LogAccess.MySQL.BinaryFormat.md)。

**注意**  
您可以配置复制以导入来自 Amazon RDS 外部的 MariaDB 或 MySQL 实例的数据库，或将数据库导出至此类实例。有关更多信息，请参阅[将数据导入 Amazon RDS for MySQL 数据库实例并减少停机时间](mysql-importing-data-reduced-downtime.md)和[使用复制从 MySQL 数据库实例中导出数据](MySQL.Procedural.Exporting.NonRDSRepl.md)。

从快照还原数据库实例或执行时间点恢复后，您可以在 RDS 控制台中查看上次从源数据库恢复的二进制日志位置。在**日志和事件**下，输入 **binlog**。二进制日志位置显示在**系统注释**下。

**Topics**
+ [

# 使用 MySQL 只读副本
](USER_MySQL.Replication.ReadReplicas.md)
+ [

# 使用基于 GTID 的复制
](mysql-replication-gtid.md)
+ [

# 配置与外部源实例之间的二进制日志文件位置复制
](MySQL.Procedural.Importing.External.Repl.md)
+ [

# 为 Amazon RDS for MySQL 配置多源复制
](mysql-multi-source-replication.md)

# 使用 MySQL 只读副本
<a name="USER_MySQL.Replication.ReadReplicas"></a>

接下来，您可以找到有关使用 RDS for MySQL 上的只读副本的特定信息。有关只读副本及其使用说明的一般信息，请参阅[使用数据库实例只读副本](USER_ReadRepl.md)。

有关 MySQL 只读副本的更多信息，请参阅以下主题。
+ [使用 MySQL 配置复制筛选条件](USER_MySQL.Replication.ReadReplicas.ReplicationFilters.md)
+ [使用 MySQL 配置延迟复制](USER_MySQL.Replication.ReadReplicas.DelayReplication.md)
+ [使用 MySQL 更新只读副本](USER_MySQL.Replication.ReadReplicas.Updates.md)
+ [使用 MySQL 处理多可用区只读副本部署](USER_MySQL.Replication.ReadReplicas.MultiAZ.md)
+ [将级联只读副本用于 RDS for MySQL](USER_MySQL.Replication.ReadReplicas.Cascading.md)
+ [监控 MySQL 只读副本的复制滞后](USER_MySQL.Replication.ReadReplicas.Monitor.md)
+ [开始和停止 MySQL 只读副本复制](USER_MySQL.Replication.ReadReplicas.StartStop.md)
+ [排查 MySQL 只读副本问题](USER_ReadRepl.Troubleshooting.md)

## 使用 MySQL 配置只读副本
<a name="USER_MySQL.Replication.ReadReplicas.Configuration"></a>

请确保在源数据库实例上启用自动备份，然后 MySQL DB 实例才能用作复制源。为此，请将备份保留期设定为非 0 值。此要求也适用于作为一个只读副本的源数据库实例的另一个只读副本。运行任何版本的 MySQL 的只读副本都支持自动备份。可以为 MySQL 数据库实例配置基于二进制日志坐标的复制。

可以在以下版本上使用全局事务标识符（GTIDS）配置复制：
+ RDS for MySQL 5.7.44 版本及更高的 5.7 版本
+ RDS for MySQL 8.0.28 版本及更高的 8.0 版本
+ RDS for MySQL 8.4.3 版本及更高的 8.4 版本

有关更多信息，请参阅 [使用基于 GTID 的复制](mysql-replication-gtid.md)。

您可以从同一区域内的一个数据库实例创建最多 15 个只读副本。为了有效地进行复制，每个只读副本具有的计算和存储资源的量应与源数据库实例的一样多。如果扩展源数据库实例，则还应扩展只读副本。

RDS for MySQL 支持级联只读副本。要了解如何配置级联只读副本，请参阅 [将级联只读副本用于 RDS for MySQL](USER_MySQL.Replication.ReadReplicas.Cascading.md)。

您可以在引用相同源数据库实例的同时，运行多个只读副本创建和删除操作。当您执行这些操作时，应将每个源实例的只读副本数限制在 15 个以内。

MySQL 数据库实例的只读副本不能使用比其源数据库实例低的数据库引擎版本。

### 准备使用 MyISAM 的 MySQL 数据库实例
<a name="USER_MySQL.Replication.ReadReplicas.Configuration-MyISAM-Instances"></a>

如果 MySQL 数据库实例使用的是 MyISAM 等非事务性引擎，则将需要执行以下步骤才能成功地设置只读副本。需要执行这些步骤，以确保只读副本具有一致的数据副本。如果您的所有表使用的都是事务性引擎 (如 InnoDB)，则无需执行这些步骤。

1. 停止源数据库实例中的非事务性表上的所有数据操作语言 (DML) 和数据定义语言 (DDL) 操作，然后等待它们完成。SELECT 语句可以继续运行。

1. 刷新并锁定源数据库实例中的表。

1. 使用以下各节中的某种方法创建只读副本。

1. 使用如 `DescribeDBInstances` API 操作检查只读副本创建的进度。有只读副本可用后，即解除对源数据库实例的表的锁定，然后继续进行正常的数据库操作。

# 使用 MySQL 配置复制筛选条件
<a name="USER_MySQL.Replication.ReadReplicas.ReplicationFilters"></a>

您可以使用复制筛选条件来指定使用只读副本的数据库和表。复制筛选条件可以将数据库和表包含在复制之中或排除在复制之外。

以下是复制筛选条件的一些使用案例：
+ 缩减只读副本的大小。使用复制筛选，您可以排除只读副本上不需要的数据库和表。
+ 出于安全原因，将数据库和表从只读副本中排除。
+ 在不同只读副本中为特定使用案例复制不同的数据库和表。例如，您可以使用特定的只读副本进行分析或分片。
+ 对于在不同 AWS 区域中具有只读副本的数据库实例，要在不同的 AWS 区域中复制不同的数据库或表。

**注意**  
您还可以使用复制筛选条件来指定使用入站复制拓扑中裴志伟副本的主 MySQL 数据库实例的数据库和表。有关此配置的更多信息，请参阅[配置与外部源实例之间的二进制日志文件位置复制](MySQL.Procedural.Importing.External.Repl.md)。

**Topics**
+ [

## 设置 RDS for MySQL 的复制筛选参数
](#USER_MySQL.Replication.ReadReplicas.ReplicationFilters.Configuring)
+ [

## RDS for MySQL 的复制筛选限制
](#USER_MySQL.Replication.ReadReplicas.ReplicationFilters.Limitations)
+ [

## RDS for MySQL 的复制筛选示例
](#USER_MySQL.Replication.ReadReplicas.ReplicationFilters.Examples)
+ [

## 查看只读副本的复制筛选条件
](#USER_MySQL.Replication.ReadReplicas.ReplicationFilters.Viewing)

## 设置 RDS for MySQL 的复制筛选参数
<a name="USER_MySQL.Replication.ReadReplicas.ReplicationFilters.Configuring"></a>

要配置复制筛选条件，请在只读副本上设置以下复制筛选参数：
+ `replicate-do-db` –将更改复制到指定的数据库。为只读副本设置此参数时，仅复制参数中指定的数据库。
+ `replicate-ignore-db` –不将更改复制到指定的数据库。为只读副本设置 `replicate-do-db` 参数时，不会评估此参数。
+ `replicate-do-table` –将更改复制到指定的表。为只读副本设置此参数时，仅复制参数中指定的表。此外，设置 `replicate-do-db` 或 `replicate-ignore-db` 参数时，请确保包含指定表的数据库包含在使用只读副本的复制中。
+ `replicate-ignore-table` –不将更改复制到指定的表。为只读副本设置 `replicate-do-table` 参数时，不会评估此参数。
+ `replicate-wild-do-table` – 根据指定的数据库和表名模式复制表。支持 `%` 和 `_` 通配符。设置 `replicate-do-db` 或 `replicate-ignore-db` 参数时，请确保包含指定表的数据库包含在使用只读副本的复制中。
+ `replicate-wild-ignore-table` –不基于指定的数据库和表名模式复制表。支持 `%` 和 `_` 通配符。为只读副本设置 `replicate-do-table` 或 `replicate-wild-do-table` 参数时，不会评估此参数。

将按这些参数列出的顺序对其进行评估。有关这些参数如何运行的更多信息，请参阅 MySQL 文档：
+ 有关一般信息，请参阅[副本服务器选项和变量](https://dev.mysql.com/doc/refman/8.0/en/replication-options-replica.html)。
+ 有关如何评估数据库复制筛选参数的信息，请参阅[评估数据库级复制和二进制日志记录选项](https://dev.mysql.com/doc/refman/8.0/en/replication-rules-db-options.html)。
+ 有关如何评估表复制筛选参数的信息，请参阅[评估表级复制选项](https://dev.mysql.com/doc/refman/8.0/en/replication-rules-table-options.html)。

默认情况下，这些参数中的每个参数都具有一个空值。在每个只读副本上，您可以使用这些参数来设置、更改和删除复制筛选条件。设置其中一个参数时，请用逗号将各筛选条件分开。

您可以在 `%` 和 `_` 参数中使用 `replicate-wild-do-table` 和 `replicate-wild-ignore-table` 通配符。`%` 通配符可以匹配任意数量的字符，而 `_` 通配符只能匹配一个字符。

源数据库实例的二进制日志记录格式对于复制非常重要，因为它决定了数据更改的记录。`binlog_format` 参数的设置将决定复制是基于行还是基于语句的复制。有关更多信息，请参阅“[为单可用区数据库配置 RDS for MySQL 二进制日志记录](USER_LogAccess.MySQL.BinaryFormat.md)”。

**注意**  
无论源数据库实例上的 `binlog_format` 设置如何，所有数据定义语言 (DDL) 语句都将作为语句进行复制。

## RDS for MySQL 的复制筛选限制
<a name="USER_MySQL.Replication.ReadReplicas.ReplicationFilters.Limitations"></a>

以下限制适用于对 RDS for MySQL 进行复制筛选：
+ 每个复制筛选参数不得超过 2000 个字符。
+ 参数值的复制筛选条件中不支持逗号。在参数列表中，逗号只能用作值分隔符。例如，不支持 `ParameterValue='`a,b`'`，但支持 `ParameterValue='a,b'`。
+ 不支持用于二进制日志筛选的 MySQL `--binlog-do-db` 和 `--binlog-ignore-db` 选项。
+ 复制筛选不支持 XA 事务。

  有关更多信息，请参阅 MySQL 文档中的[XA 事务限制](https://dev.mysql.com/doc/refman/8.0/en/xa-restrictions.html)。

## RDS for MySQL 的复制筛选示例
<a name="USER_MySQL.Replication.ReadReplicas.ReplicationFilters.Examples"></a>

要为只读副本配置复制筛选，请修改与只读副本关联的参数组中的复制筛选参数。

**注意**  
您无法修改默认参数组。如果只读副本使用默认参数组，请创建新的参数组并将其与只读副本关联。有关数据库参数组的更多信息，请参阅 [Amazon RDS 的参数组](USER_WorkingWithParamGroups.md)。

您可以使用 AWS 管理控制台、AWS CLI 或 RDS API 在参数组中设置参数。有关设置参数的信息，请参阅 [在 Amazon RDS 中修改数据库参数组中的参数](USER_WorkingWithParamGroups.Modifying.md)。在参数组中设置参数时，与参数组关联的所有数据库实例都使用参数设置。如果在参数组中设置复制筛选参数，请确保参数组仅与只读副本关联。将源数据库实例的复制筛选参数留空。

以下示例使用 AWS CLI 设置参数。这些示例将 `ApplyMethod` 设置为 `immediate`，以便在 CLI 命令完成后立即发生参数更改。如果希望在只读副本重新启动后应用待处理的更改，请将 `ApplyMethod` 设置为 `pending-reboot`。

以下示例设置了复制筛选条件：
+ [Including databases in replication](#rep-filter-in-dbs-mysql)
+ [Including tables in replication](#rep-filter-in-tables-mysql)
+ [Including tables in replication with wildcard characters](#rep-filter-in-tables-wildcards-mysql)
+ [Excluding databases from replication](#rep-filter-ex-dbs-mysql)
+ [Excluding tables from replication](#rep-filter-ex-tables-mysql)
+ [Excluding tables from replication using wildcard characters](#rep-filter-ex-tables-wildcards-mysql)<a name="rep-filter-in-dbs-mysql"></a>

**Example 将数据库包含在复制之中**  
以下示例将 `mydb1` 和 `mydb2` 数据库包含在复制之内。  
对于 Linux、macOS 或 Unix：  

```
aws rds modify-db-parameter-group \
  --db-parameter-group-name myparametergroup \
  --parameters "ParameterName=replicate-do-db,ParameterValue='mydb1,mydb2',ApplyMethod=immediate"
```
对于：Windows  

```
aws rds modify-db-parameter-group ^
  --db-parameter-group-name myparametergroup ^
  --parameters "ParameterName=replicate-do-db,ParameterValue='mydb1,mydb2',ApplyMethod=immediate"
```<a name="rep-filter-in-tables-mysql"></a>

**Example 将表包含在复制之中**  
以下示例将数据库 `table1` 中的 `table2` 和 `mydb1` 表包含在复制之中。  
对于 Linux、macOS 或 Unix：  

```
aws rds modify-db-parameter-group \
  --db-parameter-group-name myparametergroup \
  --parameters "ParameterName=replicate-do-table,ParameterValue='mydb1.table1,mydb1.table2',ApplyMethod=immediate"
```
对于：Windows  

```
aws rds modify-db-parameter-group ^
  --db-parameter-group-name myparametergroup ^
  --parameters "ParameterName=replicate-do-table,ParameterValue='mydb1.table1,mydb1.table2',ApplyMethod=immediate"
```<a name="rep-filter-in-tables-wildcards-mysql"></a>

**Example 使用通配符将表包含在复制之中**  
以下示例将数据库 `order` 中名称以 `return` 和 `mydb` 开头的表包含在复制之中。  
对于 Linux、macOS 或 Unix：  

```
aws rds modify-db-parameter-group \
  --db-parameter-group-name myparametergroup \
  --parameters "ParameterName=replicate-wild-do-table,ParameterValue='mydb.order%,mydb.return%',ApplyMethod=immediate"
```
对于：Windows  

```
aws rds modify-db-parameter-group ^
  --db-parameter-group-name myparametergroup ^
  --parameters "ParameterName=replicate-wild-do-table,ParameterValue='mydb.order%,mydb.return%',ApplyMethod=immediate"
```<a name="rep-filter-ex-dbs-mysql"></a>

**Example 将数据库排除在复制之外**  
以下示例将 `mydb5` 和 `mydb6` 数据库排除在复制之外。  
对于 Linux、macOS 或 Unix：  

```
aws rds modify-db-parameter-group \
  --db-parameter-group-name myparametergroup \
  --parameters "ParameterName=replicate-ignore-db,ParameterValue='mydb5,mydb6',ApplyMethod=immediate"
```
对于：Windows  

```
aws rds modify-db-parameter-group ^
  --db-parameter-group-name myparametergroup ^
  --parameters "ParameterName=replicate-ignore-db,ParameterValue='mydb5,mydb6',ApplyMethod=immediate"
```<a name="rep-filter-ex-tables-mysql"></a>

**Example 将表排除在复制之外**  
以下示例将数据库 `mydb5` 中的表 `table1` 和数据库 `mydb6` 中的表 `table2` 排除在复制之外。  
对于 Linux、macOS 或 Unix：  

```
aws rds modify-db-parameter-group \
  --db-parameter-group-name myparametergroup \
  --parameters "ParameterName=replicate-ignore-table,ParameterValue='mydb5.table1,mydb6.table2',ApplyMethod=immediate"
```
对于：Windows  

```
aws rds modify-db-parameter-group ^
  --db-parameter-group-name myparametergroup ^
  --parameters "ParameterName=replicate-ignore-table,ParameterValue='mydb5.table1,mydb6.table2',ApplyMethod=immediate"
```<a name="rep-filter-ex-tables-wildcards-mysql"></a>

**Example 使用通配符将表排除在复制之外**  
以下示例将数据库 `order` 中名称以 `return` 和 `mydb7` 开头的表排除在复制之外。  
对于 Linux、macOS 或 Unix：  

```
aws rds modify-db-parameter-group \
  --db-parameter-group-name myparametergroup \
  --parameters "ParameterName=replicate-wild-ignore-table,ParameterValue='mydb7.order%,mydb7.return%',ApplyMethod=immediate"
```
对于：Windows  

```
aws rds modify-db-parameter-group ^
  --db-parameter-group-name myparametergroup ^
  --parameters "ParameterName=replicate-wild-ignore-table,ParameterValue='mydb7.order%,mydb7.return%',ApplyMethod=immediate"
```

## 查看只读副本的复制筛选条件
<a name="USER_MySQL.Replication.ReadReplicas.ReplicationFilters.Viewing"></a>

您可以通过以下方式查看只读副本的复制筛选条件：
+ 检查与只读副本关联的参数组中复制筛选参数的设置。

  有关说明，请参阅[在 Amazon RDS 中查看数据库参数组的参数值](USER_WorkingWithParamGroups.Viewing.md)。
+ 在 MySQL 客户端中，连接到只读副本并运行 `SHOW REPLICA STATUS` 语句。

  在输出中，以下字段显示了只读副本的复制筛选条件：
  + `Replicate_Do_DB`
  + `Replicate_Ignore_DB`
  + `Replicate_Do_Table`
  + `Replicate_Ignore_Table`
  + `Replicate_Wild_Do_Table`
  + `Replicate_Wild_Ignore_Table`

  有关这些字段的更多信息，请参阅 MySQL 文档中的[检查复制状态](https://dev.mysql.com/doc/refman/8.0/en/replication-administration-status.html)。

# 使用 MySQL 配置延迟复制
<a name="USER_MySQL.Replication.ReadReplicas.DelayReplication"></a>

可以使用延迟复制作为灾难恢复策略。使用延迟复制，可指定最短的时间（以秒为单位）以延迟从源到只读副本的复制。如果出现灾难（如意外删除了表），可完成以下步骤以快速从灾难恢复：
+ 在导致灾难的更改发送到它之前停止复制到只读副本。

  使用 [mysql.rds\$1stop\$1replication](mysql-stored-proc-replicating.md#mysql_rds_stop_replication) 存储过程停止复制。
+ 开始复制并指定复制在日志文件位置处自动停止。

  使用 [mysql.rds\$1start\$1replication\$1until](mysql-stored-proc-replicating.md#mysql_rds_start_replication_until) 存储过程指定就位于灾难恢复之前的位置。
+ 按照[将只读副本提升为独立的数据库实例](USER_ReadRepl.Promote.md)中的说明，将只读副本提升为新的源数据库实例。

**注意**  
在 RDS for MySQL 8.4 上，支持针对 MySQL 8.4.3 及更高版本进行延迟复制。在 RDS for MySQL 8.0 上，支持针对 MySQL 8.0.28 及更高版本进行延迟复制。在 RDS for MySQL 5.7 上，支持针对 MySQL 5.7.44 及更高版本进行延迟复制。
使用存储过程配置延迟复制。无法使用AWS 管理控制台、AWS CLI 或 Amazon RDS API 配置延迟复制。
您可以在以下版本的延迟复制配置中使用基于全局事务标识符（GTID）的复制。  
RDS for MySQL 5.7.44 版本及更高的 5.7 版本
RDS for MySQL 8.0.28 版本及更高的 8.0 版本
RDS for MySQL 8.4.3 版本及更高的 8.4 版本
如果使用基于 GTID 的复制，请使用 [mysql.rds\$1start\$1replication\$1until\$1gtid](mysql-stored-proc-gtid.md#mysql_rds_start_replication_until_gtid) 存储过程而不是 [mysql.rds\$1start\$1replication\$1until](mysql-stored-proc-replicating.md#mysql_rds_start_replication_until) 存储过程。有关基于 GTID 的复制的更多信息，请参阅[使用基于 GTID 的复制](mysql-replication-gtid.md)。

**Topics**
+ [

## 在创建只读副本时配置延迟复制
](#USER_MySQL.Replication.ReadReplicas.DelayReplication.ReplicaCreation)
+ [

## 修改现有只读副本的延迟复制
](#USER_MySQL.Replication.ReadReplicas.DelayReplication.ExistingReplica)
+ [

## 设置停止复制到只读副本的位置
](#USER_MySQL.Replication.ReadReplicas.DelayReplication.StartUntil)
+ [

## 提升只读副本
](#USER_MySQL.Replication.ReadReplicas.DelayReplication.Promote)

## 在创建只读副本时配置延迟复制
<a name="USER_MySQL.Replication.ReadReplicas.DelayReplication.ReplicaCreation"></a>

要为未来通过数据库实例创建的任何只读副本配置延迟复制，请使用 [mysql.rds\$1set\$1configuration](mysql-stored-proc-configuring.md#mysql_rds_set_configuration) 参数运行 `target delay` 存储过程。

**在创建只读副本时配置延迟复制**

1. 通过使用 MySQL 客户端，以主用户身份连接到作为只读副本源的 MySQL 数据库实例。

1. 使用 [mysql.rds\$1set\$1configuration](mysql-stored-proc-configuring.md#mysql_rds_set_configuration) 参数运行 `target delay` 存储过程。

   例如，运行以下存储过程，针对从当前数据库实例创建的任何只读副本，指定将复制延迟至少一小时（3600 秒）。

   ```
   call mysql.rds_set_configuration('target delay', 3600);
   ```
**注意**  
运行此存储过程之后，将为使用 AWS CLI 或 Amazon RDS API 创建的任何只读副本配置延迟指定秒数的复制。

## 修改现有只读副本的延迟复制
<a name="USER_MySQL.Replication.ReadReplicas.DelayReplication.ExistingReplica"></a>

要修改现有只读副本的延迟复制，请运行 [mysql.rds\$1set\$1source\$1delay](mysql-stored-proc-replicating.md#mysql_rds_set_source_delay) 存储过程。

**修改现有只读副本的延迟复制**

1. 使用 MySQL 客户端，以主用户的身份连接到只读副本。

1. 使用 [mysql.rds\$1stop\$1replication](mysql-stored-proc-replicating.md#mysql_rds_stop_replication) 存储过程停止复制。

1. 运行 [mysql.rds\$1set\$1source\$1delay](mysql-stored-proc-replicating.md#mysql_rds_set_source_delay) 存储过程。

   例如，运行以下存储过程，指定复制到只读副本延迟至少一小时（3600 秒）。

   ```
   call mysql.rds_set_source_delay(3600);
   ```

1. 使用 [mysql.rds\$1start\$1replication](mysql-stored-proc-replicating.md#mysql_rds_start_replication) 存储过程开始复制。

## 设置停止复制到只读副本的位置
<a name="USER_MySQL.Replication.ReadReplicas.DelayReplication.StartUntil"></a>

停止复制到只读副本之后，可使用 [mysql.rds\$1start\$1replication\$1until](mysql-stored-proc-replicating.md#mysql_rds_start_replication_until) 存储过程开始复制，然后在指定二进制日志文件位置处停止复制。

**开始复制到只读副本并在特定位置处停止复制**

1. 通过使用 MySQL 客户端，以主用户的身份连接到源 MySQL 数据库实例。

1. 运行 [mysql.rds\$1start\$1replication\$1until](mysql-stored-proc-replicating.md#mysql_rds_start_replication_until) 存储过程。

   以下示例将启动复制并复制更改，直到它到达 `120` 二进制日志文件中的 `mysql-bin-changelog.000777` 位置。在灾难恢复方案中，假定位置 `120` 刚好位于灾难之前。

   ```
   call mysql.rds_start_replication_until(
     'mysql-bin-changelog.000777',
     120);
   ```

当到达停止点时，复制将自动停止。将生成以下 RDS 事件：`Replication has been stopped since the replica reached the stop point specified by the rds_start_replication_until stored procedure`。

## 提升只读副本
<a name="USER_MySQL.Replication.ReadReplicas.DelayReplication.Promote"></a>

在灾难恢复方案中，当复制停止后，您可以将只读副本提升为新的源数据库实例。有关提升只读副本的信息，请参阅 [将只读副本提升为独立的数据库实例](USER_ReadRepl.Promote.md)。

# 使用 MySQL 更新只读副本
<a name="USER_MySQL.Replication.ReadReplicas.Updates"></a>

只读副本旨在支持读取查询，但您可能需要偶尔进行更新。例如，您可能需要添加索引，以优化访问副本的特定类型的查询。

尽管您可以通过将只读副本的数据库参数组中的 `read_only` 参数设置为 `0` 来启用更新，但我们建议您不要这样做，因为如果读取副本与源数据库实例不兼容，则这可能会导致问题。对于维护操作，我们建议您使用蓝绿部署。有关更多信息，请参阅 [使用蓝绿部署进行数据库更新](blue-green-deployments.md)。

如果您在只读副本上禁用只读，请尽快将 `read_only` 参数的值改回为 `1`。

# 使用 MySQL 处理多可用区只读副本部署
<a name="USER_MySQL.Replication.ReadReplicas.MultiAZ"></a>

您可从单可用区或多可用区数据库实例部署中创建只读副本。您可以使用多可用区部署提高关键数据的持久性和可用性，但无法使用多可用区为只读查询提供辅助服务。您可以改为从大流量、多可用区数据库实例创建只读副本以分载只读查询。如果多可用区部署的源实例故障转移到辅助可用区，则任何关联的只读副本都将自动切换为使用辅助可用区（现在为主可用区）作为其复制源。有关更多信息，请参阅“[配置和管理 Amazon RDS 的多可用区部署](Concepts.MultiAZ.md)”。

您可以将只读副本创建为多可用区数据库实例。Amazon RDS 会在另一个可用区中创建您的副本的备用，用于支持副本的故障转移。创建您的只读副本作为多可用区数据库实例与源数据库是否为多可用区数据库实例无关。

# 将级联只读副本用于 RDS for MySQL
<a name="USER_MySQL.Replication.ReadReplicas.Cascading"></a>

RDS for MySQL 支持级联只读副本。使用*级联只读副本*，您可以扩展读取操作，而不会增加源 RDS for MySQL 数据库实例的开销。

使用级联只读副本，您的 RDS for MySQL 数据库实例会将数据发送到链中的第一个只读副本。然后，该只读副本将数据发送到链中的第二个副本，依此类推。最终结果是，链中的所有只读副本都具有来自 RDS for MySQL 数据库实例的更改，但不会只在源数据库实例上产生开销。

您可以从源 RDS for MySQL 数据库实例在链中创建一系列最多三个只读副本。例如，假设您具有 RDS for MySQL 数据库实例 `mysql-main`。您可执行以下操作：
+ 从 `mysql-main` 开始，创建链中的第一个只读副本 `read-replica-1`。
+ 接下来，从 `read-replica-1`，创建链中的下一个只读副本 `read-replica-2`。
+ 最后，从 `read-replica-2`，创建链中的第三个只读副本 `read-replica-3`。

除了 `mysql-main` 系列中的第三个级联只读副本之外，您无法创建另一个只读副本。从 RDS for MySQL 源数据库实例到一系列级联只读副本末尾的完整实例系列最多可以包含四个数据库实例。

为了使级联只读副本正常工作，每个源 RDS for MySQL 数据库实例必须开启自动备份。要对只读副本开启自动备份，请先创建只读副本，然后修改只读副本以开启自动备份。有关更多信息，请参阅 [创建只读副本](USER_ReadRepl.Create.md)。

与任何只读副本一样，您可以升级属于级联一部分的只读副本。从只读副本链中升级只读副本将从链中移除该副本。例如，假设您希望将一些工作负载从 `mysql-main` 数据库实例转移到新实例，以仅供会计部门使用。假设该示例中的链有三个只读副本，您决定升级 `read-replica-2`。该链受到如下影响：
+ 升级 `read-replica-2` 会将其从复制链中移除。
  + 现在它是一个完全读/写数据库实例。
  + 它继续复制到 `read-replica-3`，就像在升级之前那样。
+ 您的 `mysql-main` 继续复制到 `read-replica-1`。

有关升级只读副本的更多信息，请参阅[将只读副本提升为独立的数据库实例](USER_ReadRepl.Promote.md)。

# 监控 MySQL 只读副本的复制滞后
<a name="USER_MySQL.Replication.ReadReplicas.Monitor"></a>

对于 MySQL 只读副本，可以在 Amazon CloudWatch 中通过查看 Amazon RDS `ReplicaLag` 指标来监控复制滞后。`ReplicaLag` 指标报告 `Seconds_Behind_Master` 命令的 `SHOW REPLICA STATUS` 字段的值。

MySQL 复制滞后的常见原因如下所示：
+ 网络中断。
+ 对只读副本上有不同索引的表进行写入操作。如果在只读副本上将 `read_only` 参数设置为 `0`，则在只读副本变得与源数据库实例不兼容时，复制会中断。对只读副本执行维护任务之后，我们建议您将 `read_only` 参数调整回 `1`。
+ 使用 MyISAM 等非事务性存储引擎。仅 MySQL 上的 InnoDB 存储引擎支持复制。

当 `ReplicaLag` 指标达到 0 时，即表示副本已赶上源数据库实例进度。如果 `ReplicaLag` 指标返回 -1，则当前未激活复制。`ReplicaLag` = -1 等效于 `Seconds_Behind_Master` = `NULL`。

# 开始和停止 MySQL 只读副本复制
<a name="USER_MySQL.Replication.ReadReplicas.StartStop"></a>

可通过调用系统存储过程 [mysql.rds\$1stop\$1replication](mysql-stored-proc-replicating.md#mysql_rds_stop_replication) 和 [mysql.rds\$1start\$1replication](mysql-stored-proc-replicating.md#mysql_rds_start_replication)，在 Amazon RDS 数据库实例上停止再重新开始复制过程。对于长时间运行的操作 (如创建大型索引)，在两个 Amazon RDS 实例之间进行复制时可以这样做。在导入或导出数据库时，也需要停止再开始复制。有关更多信息，请参阅[将数据导入 Amazon RDS for MySQL 数据库实例并减少停机时间](mysql-importing-data-reduced-downtime.md)和[使用复制从 MySQL 数据库实例中导出数据](MySQL.Procedural.Exporting.NonRDSRepl.md)。

如果复制连续 30 天停止，不论是手动还是由于复制错误，Amazon RDS 将终止源数据库实例与所有只读副本之间的复制。这样做是为了防止源数据库实例上的存储需求增长以及长故障转移时间。只读副本数据库实例仍可用。但是无法恢复复制，因为在终止复制后，已从源数据库实例中删除只读副本所需的二进制日志。您可为源数据库实例创建新的只读副本来重新建立复制。

# 排查 MySQL 只读副本问题
<a name="USER_ReadRepl.Troubleshooting"></a>

对于 MySQL 数据库实例，在某些情况下，只读副本将显示只读副本与其源数据库实例之间的复制错误或数据不一致项（或两者）。如果在只读副本或源数据库实例失败期间未刷新某些二进制日志 (binlog) 事件或 InnoDB 重做日志，则会出现此问题。在这些情况下，请手动删除并重新创建只读副本。您可通过设置以下参数值来降低发生这种情况的可能性：`sync_binlog=1` 和 `innodb_flush_log_at_trx_commit=1`。这些设置可能降低性能，因此，请先测试其影响，然后在生产环境中实施更改。

**警告**  
建议在与源数据库实例关联的参数组中保留以下参数值：`sync_binlog=1` 和 `innodb_flush_log_at_trx_commit=1`。这些是动态参数。如果不想使用这些设置，建议在对源数据库实例执行可能导致其重启的任何操作之前，临时设置这些值。这些操作包括但不限于重启、使用故障转移重启、升级数据库版本以及更改数据库实例类或其存储。同样的建议也适用于创建源数据库实例的新只读副本。  
如果不遵循此指示，则将增加只读副本显示只读副本与其源数据库实例之间的复制错误或数据不一致项（或两者）的风险。

MySQL 的复制技术是异步的。由于它们是异步的，因此，源数据库实例上偶发的 `BinLogDiskUsage` 会增多，而只读副本上应有 `ReplicaLag`。例如，对源数据库实例的大量写入操作可以并行进行。与之对比的是，对只读副本的写入操作使用单个 I/O 线程串行进行，这会导致源实例与只读副本之间存在滞后。有关 MySQL 文档中只读副本的更多信息，请参阅[复制实施详细信息](https://dev.mysql.com/doc/refman/8.0/en/replication-implementation-details.html)。

您可通过多种方式来减少对源数据库实例的更新与对只读副本的后续更新之间的滞后，例如：
+ 将只读副本的存储大小和数据库实例类调整到与源数据库实例类似。
+ 确保源数据库实例和只读副本使用的数据库参数组中的参数设置相兼容。有关更多信息和示例，请参阅本部分后面的有关 `max_allowed_packet` 参数的讨论。

Amazon RDS 监控只读副本的复制状态，如果由于任何原因停止复制，则将只读副本实例的 `Replication State` 字段更新为 `Error`。可能会有这样的例子，在您的只读副本上运行的 DML 查询与对源数据库实例的更新冲突。

可通过查看 `Replication Error` 字段，检查 MySQL 引擎引发的关联错误的详细信息。还生成指示只读副本状态的事件，包括 [RDS-EVENT-0045](USER_Events.Messages.md#RDS-EVENT-0045)、[RDS-EVENT-0046](USER_Events.Messages.md#RDS-EVENT-0046) 和 [RDS-EVENT-0047](USER_Events.Messages.md#RDS-EVENT-0047)。有关这些事件和事件订阅的详细信息，请参阅 [使用 Amazon RDS 事件通知](USER_Events.md)。如果返回 MySQL 错误消息，则检查 [MySQL 错误消息文档](https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html)中的错误编号。

一个可导致复制出错的常见问题是只读副本的 `max_allowed_packet` 参数的值小于源数据库实例的 `max_allowed_packet` 参数的值。`max_allowed_packet` 参数是您可以在数据库参数组中设置的自定义参数。您可以使用 `max_allowed_packet` 指定可在数据库上运行的 DML 代码的最大大小。有时候，与只读副本关联的数据库参数组中的 `max_allowed_packet` 值，要小于与源数据库实例关联的数据库参数组中的 `max_allowed_packet` 值。在这些情况下，复制过程可能会引发错误 `Packet bigger than 'max_allowed_packet' bytes` 并停止复制。如需修复错误，请让源数据库实例和只读副本使用具有相同 `max_allowed_packet` 参数值的数据库参数组。

其他可导致复制错误的常见情况包括：
+ 对只读副本上的表进行写入操作。在某些情况下，您可能会在只读副本上创建索引，而该索引不同于源数据库实例上的索引。如果执行此操作，请将 `read_only` 参数设置为 `0` 以创建索引。如果您要写入到只读副本上的表，则在只读副本变得与源数据库实例不兼容时，复制会中断。对只读副本执行维护任务之后，我们建议您将 `read_only` 参数调整回 `1`。
+  使用非事务性存储引擎，如 MyISAM。只读副本需要使用事务性存储引擎。仅 MySQL 上的 InnoDB 存储引擎支持复制。
+  使用不安全的不确定性查询，如 `SYSDATE()`。有关更多信息，请参阅[确定二进制日志记录中的安全和不安全语句](https://dev.mysql.com/doc/refman/8.0/en/replication-rbr-safe-unsafe.html)。

如果您确定可安全跳过错误，那么可以按照[跳过 RDS for MySQL 的当前复制错误](Appendix.MySQL.CommonDBATasks.SkipError.md)部分中描述的步骤操作。否则，您可以先删除只读副本。然后，您可以使用相同的数据库实例标识符创建实例，以使终端节点保持与旧只读副本的终端节点相同。如果复制错误得到纠正，则 `Replication State` 将更改为 *replicating*。

# 使用基于 GTID 的复制
<a name="mysql-replication-gtid"></a>

以下内容说明了如何在 Amazon RDS for MySQL 数据库实例间使用采用二进制日志（binlog）复制的全局事务标识符（GTID）。

如果您使用的是二进制日志复制，不熟悉 MySQL 的基于 GTID 的复制，请参阅 MySQL 文档中的 [Replication with global transaction identifiers](https://dev.mysql.com/doc/refman/5.7/en/replication-gtids.html)。

以下版本支持基于 GTID 的复制：
+ 所有 RDS for MySQL 8.4 版本
+ 所有 RDS for MySQL 8.0 版本
+ 所有 RDS for MySQL 5.7 版本

复制配置中的所有 MySQL 数据库实例均必须满足该版本要求。

**Topics**
+ [

## 全局事务标识符 (GTID) 概述
](#mysql-replication-gtid.overview)
+ [

## 基于 GTID 的复制的参数
](#mysql-replication-gtid.parameters)
+ [

# 为 RDS for MySQL 的新只读副本启用基于 GTID 的复制
](mysql-replication-gtid.configuring-new-read-replicas.md)
+ [

# 为 RDS for MySQL 的现有只读副本启用基于 GTID 的复制
](mysql-replication-gtid.configuring-existing-read-replicas.md)
+ [

# 为具有只读副本的 MySQL 数据库实例禁用基于 GTID 的复制
](mysql-replication-gtid.disabling.md)

## 全局事务标识符 (GTID) 概述
<a name="mysql-replication-gtid.overview"></a>

*全局事务标识符 (GTID)* 是为提交的 MySQL 事务生成的唯一标识符。您可以使用 GTID 让二进制日志复制的故障排除更加简单便捷。

MySQL 使用两种不同类型的事务进行二进制日志复制：
+ *GTID 事务* – 由 GTID 标识的事务。
+ *匿名事务* – 未分配 GTID 的事务。

在复制配置中，GTID 在所有数据库实例中是唯一的。GTID 简化了复制配置，因为在使用它们时，您不必引用日志文件位置。通过使用 GTID，还可以更轻松地跟踪复制的事务并确定源实例和副本是否一致。

您可以使用基于 GTID 的复制，通过 RDS for MySQL 只读副本复制数据。您可以在创建新的只读副本时配置基于 GTID 的复制，也可以转换现有的只读副本以使用基于 GTID 的复制。

您还可以在与 RDS for MySQL 之间的延迟复制配置中使用基于 GTID 的复制。有关更多信息，请参阅 [使用 MySQL 配置延迟复制](USER_MySQL.Replication.ReadReplicas.DelayReplication.md)。

## 基于 GTID 的复制的参数
<a name="mysql-replication-gtid.parameters"></a>

可以使用以下参数配置基于 GTID 的复制。


| 参数 | 有效值 | 描述 | 
| --- | --- | --- | 
|  `gtid_mode`  |  `OFF`, `OFF_PERMISSIVE`, `ON_PERMISSIVE`, `ON`  |  `OFF` 指定新事务是匿名事务（即，没有 GTID），并且事务必须是匿名事务才能复制。 `OFF_PERMISSIVE` 指定新事务是匿名事务，但可以复制所有事务。 `ON_PERMISSIVE` 指定新事务是 GTID 事务，但可以复制所有事务。 `ON` 指定新事务是 GTID 事务，并且事务必须是 GTID 事务才能复制。  | 
|  `enforce_gtid_consistency`  |  `OFF`, `ON`, `WARN`  |  `OFF` 允许事务违反 GTID 一致性。 `ON` 禁止事务违反 GTID 一致性。 `WARN` 允许事务违反 GTID 一致性，但在违反一致性时生成警告。  | 

**注意**  
在 AWS 管理控制台中，`gtid_mode` 参数显示为 `gtid-mode`。

对于基于 GTID 的复制，请为数据库实例或只读副本的参数组使用这些设置：
+ `ON` 和 `ON_PERMISSIVE` 仅适用于从 RDS 数据库实例的传出复制。这两个值都可以让 RDS 数据库实例为复制的事务使用 GTID。`ON` 要求目标数据库也使用基于 GTID 的复制。`ON_PERMISSIVE` 让基于 GTID 的复制成为目标数据库上的可选项。
+ `OFF_PERMISSIVE`（如果设置）表明您的 RDS 数据库实例可以接受来自源数据库的传入复制。无论源数据库是否使用基于 GTID 的复制，它们都可以这样做。
+ `OFF`（如果设置）表明您的 RDS 数据库实例只接受来自不使用基于 GTID 的复制的源数据库的传入复制。

有关参数组的更多信息，请参阅 [Amazon RDS 的参数组](USER_WorkingWithParamGroups.md)。

# 为 RDS for MySQL 的新只读副本启用基于 GTID 的复制
<a name="mysql-replication-gtid.configuring-new-read-replicas"></a>

在为 RDS for MySQL 数据库实例启用基于 GTID 的复制时，将自动为数据库实例的只读副本配置基于 GTID 的复制。

**为新的只读副本启用基于 GTID 的复制**

1. 确保与数据库实例关联的参数组具有以下参数设置：
   + `gtid_mode` – `ON` 或 `ON_PERMISSIVE`
   + `enforce_gtid_consistency` – `ON`

   有关使用参数组设置配置参数的更多信息，请参阅 [Amazon RDS 的参数组](USER_WorkingWithParamGroups.md)。

1. 如果更改了数据库实例的参数组，请重新引导数据库实例。有关执行该操作的更多信息，请参阅[重启数据库实例](USER_RebootInstance.md)。

1.  创建数据库实例的一个或多个只读副本。有关执行该操作的更多信息，请参阅[创建只读副本](USER_ReadRepl.Create.md)。

Amazon RDS 尝试使用 `MASTER_AUTO_POSITION` 在 MySQL 数据库实例和只读副本之间配置基于 GTID 的复制。如果尝试失败，Amazon RDS 将使用日志文件位置与只读副本之间进行复制。有关 `MASTER_AUTO_POSITION` 的更多信息，请参阅 MySQL 文档中的 [GTID 自动定位](https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-auto-positioning.html)。

# 为 RDS for MySQL 的现有只读副本启用基于 GTID 的复制
<a name="mysql-replication-gtid.configuring-existing-read-replicas"></a>

对于具有不使用基于 GTID 的复制的只读副本的现有 MySQL 数据库实例，您可以在数据库实例和只读副本之间配置基于 GTID 的复制。

**为现有的只读副本启用基于 GTID 的复制**

1. 如果数据库实例或任何只读副本使用了低于 8.0.26 的 RDS for MySQL 8.0.x 版本，请将数据库实例或只读副本升级为 8.0.26 或更高的 MySQL 8.0 版本。所有 RDS for MySQL 8.4 版本和 5.7 版本均支持基于 GTID 的复制。

   有关更多信息，请参阅 [升级 RDS for MySQL 数据库引擎](USER_UpgradeDBInstance.MySQL.md)。

1. （可选）重置 GTID 参数并测试数据库实例和只读副本的行为：

   1. 确保与数据库实例和每个只读副本关联的参数组将 `enforce_gtid_consistency` 参数设置为 `WARN`。

      有关使用参数组设置配置参数的更多信息，请参阅 [Amazon RDS 的参数组](USER_WorkingWithParamGroups.md)。

   1. 如果更改了数据库实例的参数组，请重新引导数据库实例。如果更改了只读副本的参数组，请重新引导只读副本。

      有关更多信息，请参阅“[重启数据库实例](USER_RebootInstance.md)”。

   1. 运行具有正常工作负载的数据库实例和只读副本并监控日志文件。

      如果看到有关与 GTID 不兼容的事务的警告，请调整您的应用程序，以使其仅使用与 GTID 兼容的功能。在继续执行下一步之前，请确保数据库实例未生成有关与 GTID 不兼容的事务的任何警告。

1. 为允许匿名事务的基于 GTID 的复制重置 GTID 参数，直到只读副本已处理所有这些事务。

   1. 确保与数据库实例和每个只读副本关联的参数组具有以下参数设置：
      + `gtid_mode` – `ON_PERMISSIVE`
      + `enforce_gtid_consistency` – `ON`

   1. 如果更改了数据库实例的参数组，请重新引导数据库实例。如果更改了只读副本的参数组，请重新引导只读副本。

1. 等待复制所有匿名事务。要检查是否复制了这些事务，请执行以下操作：

   1. 在源数据库实例上运行以下语句。

      **MySQL 8.4**

      ```
      SHOW BINARY LOG STATUS;
      ```

      **MySQL 5.7 和 8.0**

      ```
      SHOW MASTER STATUS;
      ```

      记下 `File` 和 `Position` 列中的值。

   1. 在每个只读副本上，使用上一步中的源实例上的文件和位置信息运行以下查询。

      ```
      SELECT MASTER_POS_WAIT('file', position);
      ```

      例如，如果文件名是 `mysql-bin-changelog.000031` 并且位置是 `107`，请运行以下语句。

      ```
      SELECT MASTER_POS_WAIT('mysql-bin-changelog.000031', 107);
      ```

      如果只读副本超过指定的位置，查询将立即返回。否则，该函数将等待一段时间。在查询返回所有只读副本的结果时，请继续执行下一步。

1. 仅重置基于 GTID 的复制的 GTID 参数。

   1. 确保与数据库实例和每个只读副本关联的参数组具有以下参数设置：
      + `gtid_mode` – `ON`
      + `enforce_gtid_consistency` – `ON`

   1. 重新引导数据库实例和每个只读副本。

1. 在每个只读副本上，运行以下过程。

   **MySQL 8.4 及更高的主要版本**

   ```
   CALL mysql.rds_set_source_auto_position(1);
   ```

   **MySQL 8.0 及更低的主要版本**

   ```
   CALL mysql.rds_set_master_auto_position(1);
   ```

# 为具有只读副本的 MySQL 数据库实例禁用基于 GTID 的复制
<a name="mysql-replication-gtid.disabling"></a>

您可以为 一个具有只读副本的 MySQL 数据库实例。

**为 具有只读副本的 MySQL 数据库实例禁用基于 GTID 的复制**

1. 在每个只读副本上，运行以下过程：

   **MySQL 8.4 及更高的主要版本**

   ```
   CALL mysql.rds_set_source_auto_position(0);
   ```

   **MySQL 8.0 及更低的主要版本**

   ```
   CALL mysql.rds_set_master_auto_position(0);
   ```

1. 将 `gtid_mode` 重置为 `ON_PERMISSIVE`。

   1. 确保与 MySQL 数据库实例和每个只读副本关联的参数组将 `gtid_mode` 设置为 `ON_PERMISSIVE`。

      有关使用参数组设置配置参数的更多信息，请参阅 [Amazon RDS 的参数组](USER_WorkingWithParamGroups.md)。

   1. 重新引导 MySQL 数据库实例和每个只读副本。有关重新引导的更多信息，请参阅[重启数据库实例](USER_RebootInstance.md)。

1. 将 `gtid_mode` 重置为 `OFF_PERMISSIVE`。

   1. 确保与 MySQL 数据库实例和每个只读副本关联的参数组将 `gtid_mode` 设置为 `OFF_PERMISSIVE`。

   1. 重新引导 MySQL 数据库实例和每个只读副本。

1. 等待在所有只读副本上应用所有 GTID 事务。要检查是否应用了这些事务，请按以下步骤操作：

   1. 在 MySQL 数据库实例上，运行以下命令：

      **MySQL 8.4**

      ```
      SHOW BINARY LOG STATUS
      ```

      **MySQL 5.7 和 8.0**

      ```
      SHOW MASTER STATUS
      ```

      您的输出应类似于以下输出。

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

      记下输出中的文件和位置。

   1. 在每个只读副本上，使用上一步中的源实例上的文件和位置信息运行以下查询：

      **MySQL 8.4 和 MySQL 8.0.26 及更高的 MySQL 8.0 版本**

      ```
      SELECT SOURCE_POS_WAIT('file', position);
      ```

      **MySQL 5.7**\$1

      ```
      SELECT MASTER_POS_WAIT('file', position);
      ```

      例如，如果文件名是 `mysql-bin-changelog.000031` 并且位置是 `107`，请运行以下语句：

      **MySQL 8.4 和 MySQL 8.0.26 及更高的 MySQL 8.0 版本**

      ```
      SELECT SOURCE_POS_WAIT('mysql-bin-changelog.000031', 107);
      ```

      **MySQL 5.7**\$1

      ```
      SELECT MASTER_POS_WAIT('mysql-bin-changelog.000031', 107);
      ```

1. 重置 GTID 参数以禁用基于 GTID 的复制。

   1. 确保与 MySQL 数据库实例和每个只读副本关联的参数组具有以下参数设置：
      + `gtid_mode` – `OFF`
      + `enforce_gtid_consistency` – `OFF`

   1. 重新引导 MySQL 数据库实例和每个只读副本。

# 配置与外部源实例之间的二进制日志文件位置复制
<a name="MySQL.Procedural.Importing.External.Repl"></a>

您可以使用二进制日志文件复制来设置 RDS for MySQL 或 MariaDB 数据库实例与 Amazon RDS 外部的 MySQL 或 MariaDB 实例之间的复制。

**Topics**
+ [

## 开始前的准备工作
](#MySQL.Procedural.Importing.External.Repl.BeforeYouBegin)
+ [

## 配置与外部源实例之间的二进制日志文件位置复制
](#MySQL.Procedural.Importing.External.Repl.Procedure)

## 开始前的准备工作
<a name="MySQL.Procedural.Importing.External.Repl.BeforeYouBegin"></a>

您可以使用复制的事务的二进制日志文件位置配置复制。

对 Amazon RDS 数据库实例启动复制功能所需的权限受到限制且对 Amazon RDS 主用户不可用。因此，请确保使用 Amazon RDS [mysql.rds\$1set\$1external\$1master（RDS for MariaDB 和 RDS for MySQL 主要版本 8.0 及更低版本）](mysql-stored-proc-replicating.md#mysql_rds_set_external_master) 或 [mysql.rds\$1set\$1external\$1source（RDS for MySQL 主要版本 8.4 及更高版本）](mysql-stored-proc-replicating.md#mysql_rds_set_external_source) 以及 [mysql.rds\$1start\$1replication](mysql-stored-proc-replicating.md#mysql_rds_start_replication) 命令来设置活动数据库和 Amazon RDS 数据库之间的复制。

要为 MySQL 或 MariaDB 数据库设置二进制日志记录格式，请更新 `binlog_format` 参数。如果您的数据库实例使用默认数据库实例参数组，请创建一个新的数据库参数组来修改 `binlog_format` 参数。在 MariaDB 和 MySQL 8.0 及更低版本中，`binlog_format` 默认设置为 `MIXED`。不过，如果您需要特定的二进制日志 (binlog) 格式，也可以将 `binlog_format` 设置为 `ROW` 或 `STATEMENT`。重启您的数据库实例以使更改生效。在 MySQL 8.4 及更高版本中，`binlog_format` 默认设置为 `ROW`。

有关设置 `binlog_format` 参数的信息，请参阅[为单可用区数据库配置 RDS for MySQL 二进制日志记录](USER_LogAccess.MySQL.BinaryFormat.md)。有关不同 MySQL 复制类型的含义的信息，请参阅 MySQL 文档中的[基于语句和基于行的复制的优点和缺点](https://dev.mysql.com/doc/refman/8.0/en/replication-sbr-rbr.html)。

## 配置与外部源实例之间的二进制日志文件位置复制
<a name="MySQL.Procedural.Importing.External.Repl.Procedure"></a>

对 Amazon RDS 设置外部源实例和副本时，请遵循以下准则：
+ 监控作为副本的 Amazon RDS 数据库实例的失效转移事件。如果发生失效转移，则可能会在具有不同的网络地址的新主机上重新创建作为副本的数据库实例。有关如何监控失效转移事件的信息，请参阅[使用 Amazon RDS 事件通知](USER_Events.md)。
+ 在您的源实例上维护二进制日志，直至您确认其已应用于副本。该维护确保在发生故障时可以还原源实例。
+ 对 Amazon RDS 数据库实例启用自动备份。通过启用自动备份，可以确保在需要重新同步源实例和副本时能够将副本还原到特定时间点。有关备份和时间点还原的信息，请参阅[备份、还原和导出数据](CHAP_CommonTasks.BackupRestore.md)。

**配置与外部源实例之间的二进制日志文件复制**

1. 将源 MySQL 或 MariaDB 实例设置为只读。

   ```
   mysql> FLUSH TABLES WITH READ LOCK;
   mysql> SET GLOBAL read_only = ON;
   ```

1. 对源 MySQL 或 MariaDB 实例运行 `SHOW MASTER STATUS` 命令以确定二进制日志位置。

   您将收到类似于以下示例的输出。

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

1. 使用 `mysqldump` 将数据库从外部实例复制到 Amazon RDS 数据库实例。对于非常大的数据库，您可能需要使用[将数据导入 Amazon RDS for MySQL 数据库实例并减少停机时间](mysql-importing-data-reduced-downtime.md)中的过程。

   对于 Linux、macOS 或 Unix：

   ```
   mysqldump --databases database_name \
       --single-transaction \
       --compress \
       --order-by-primary \
       -u local_user \
       -plocal_password | mysql \
           --host=hostname \
           --port=3306 \
           -u RDS_user_name \
           -pRDS_password
   ```

   对于：Windows

   ```
   mysqldump --databases database_name ^
       --single-transaction ^
       --compress ^
       --order-by-primary ^
       -u local_user ^
       -plocal_password | mysql ^
           --host=hostname ^
           --port=3306 ^
           -u RDS_user_name ^
           -pRDS_password
   ```
**注意**  
确保 `-p` 选项和输入的密码之间没有空格。

   要指定主机名、用户名、端口和密码以连接到 Amazon RDS 数据库实例，请在 `--host` 命令中使用 `--user (-u)`、`--port`、`-p` 和 `mysql` 选项。主机名是 Amazon RDS 数据库实例端点中的域名服务 (DNS) 名称，例如 `myinstance.123456789012.us-east-1.rds.amazonaws.com`。您可以在 AWS 管理控制台上的实例详细信息中找到端点值。

1. 再次将源 MySQL 或 MariaDB 实例设置为可写。

   ```
   mysql> SET GLOBAL read_only = OFF;
   mysql> UNLOCK TABLES;
   ```

   有关生成备份以用于复制的更多信息，请参阅 [MySQL 文档](https://dev.mysql.com/doc/refman/8.0/en/replication-solutions-backups-read-only.html)。

1. 在 AWS 管理控制台 中，将托管外部数据库的服务器的 IP 地址添加到 Amazon RDS 数据库实例的 Virtual Private Cloud (VPC) 安全组中。有关修改 VPC 安全组的更多信息，请参阅 *Amazon Virtual Private Cloud 用户指南* 中的[您的 VPC 的安全组](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)。

   在满足以下条件时，IP 地址可能会发生更改：
   + 您正在使用公有 IP 地址在外部源实例和数据库实例之间进行通信。
   + 外部源实例已停止并重新启动。

   如果满足这些条件，请在添加 IP 地址之前先对其进行验证。

   您可能还需要配置本地网络，以允许来自 Amazon RDS 数据库实例的 IP 地址的连接。通过执行此操作，您的本地网络可以与外部 MySQL 或 MariaDB 实例进行通信。要查找 Amazon RDS 数据库实例的 IP 地址，请使用 `host` 命令。

   ```
   host db_instance_endpoint
   ```

   主机名是 Amazon RDS 数据库实例端点中的 DNS 名称。

1. 通过使用所选的客户端，连接到外部实例并创建要用于复制的用户。请仅将该账户用于复制，并将其限制为您的域以提高安全性。示例如下：

   ```
   CREATE USER 'repl_user'@'mydomain.com' IDENTIFIED BY 'password';
   ```
**注意**  
作为安全最佳实践，请指定除此处所示提示以外的密码。

1. 对于外部 实例，向复制用户授予 `REPLICATION CLIENT` 和 `REPLICATION SLAVE` 权限。例如，要为您的域的“`REPLICATION CLIENT`”用户授予对所有数据库的 `REPLICATION SLAVE` 和 `repl_user` 权限，请发出以下命令。

   ```
   GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user'@'mydomain.com';
   ```

1. 将 Amazon RDS 数据库实例设置为副本。为此，请先以主用户身份连接到 Amazon RDS 数据库实例。然后使用 [mysql.rds\$1set\$1external\$1source（RDS for MySQL 主要版本 8.4 及更高版本）](mysql-stored-proc-replicating.md#mysql_rds_set_external_source) 或 [mysql.rds\$1set\$1external\$1master（RDS for MariaDB 和 RDS for MySQL 主要版本 8.0 及更低版本）](mysql-stored-proc-replicating.md#mysql_rds_set_external_master) 命令，将外部 MySQL 或 MariaDB 数据库标识为源实例。使用在步骤 2 中确定的主日志文件名和主日志位置。下面是一些命令示例。

   **MySQL 8.4**

   ```
   CALL mysql.rds_set_external_source ('mysourceserver.mydomain.com', 3306, 'repl_user', 'password', 'mysql-bin-changelog.000031', 107, 1);
   ```

   **MariaDB 以及 MySQL 8.0 和 5.7**

   ```
   CALL mysql.rds_set_external_master ('mymasterserver.mydomain.com', 3306, 'repl_user', 'password', 'mysql-bin-changelog.000031', 107, 1);
   ```
**注意**  
在 RDS for MySQL 上，可以选择通过运行 [mysql.rds\$1set\$1external\$1source\$1with\$1delay（RDS for MySQL 主要版本 8.4 及更高版本）](mysql-stored-proc-replicating.md#mysql_rds_set_external_source_with_delay) 或 [mysql.rds\$1set\$1external\$1master\$1with\$1delay（RDS for MariaDB 和 RDS for MySQL 主要版本 8.0 及更低版本）](mysql-stored-proc-replicating.md#mysql_rds_set_external_master_with_delay) 存储过程来使用延迟复制。在 RDS for MySQL 中，使用延迟复制的一个原因是，使用 [mysql.rds\$1start\$1replication\$1until](mysql-stored-proc-replicating.md#mysql_rds_start_replication_until) 存储过程打开灾难恢复。目前，RDS for MariaDB 支持延迟复制，但不支持 `mysql.rds_start_replication_until` 过程。

1. 在 Amazon RDS 数据库实例上，发出 [mysql.rds\$1start\$1replication](mysql-stored-proc-replicating.md#mysql_rds_start_replication) 命令以启动复制。

   ```
   CALL mysql.rds_start_replication;
   ```

# 为 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 的复制。
+ 数据库集群上的失效转移事件会移除多源复制配置。还原该配置需要重复配置步骤。