使用 MySQL 只读副本 - Amazon Relational Database Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

使用 MySQL 只读副本

接下来,您可以找到有关使用 Amazon RDS for Oracle 上的只读副本的特定信息。有关只读副本及其使用说明的一般信息,请参阅使用只读副本

MySQL 只读副本配置

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

在 Amazon RDS for MySQL 版本 5.7.23 和更高的 MySQL 5.7 版本中,您可以使用全局事务标识符 (GTID) 配置复制。有关更多信息,请参阅 在 RDS for MySQL 中使用基于 GTID 的复制

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

如果一个只读副本运行的是任何版本的 MySQL 5.6 和更高版本,则可指定其作为另一个只读副本的源数据库实例。例如,可从 MyDBInstance 创建 ReadReplica1,然后从 ReadReplica1 创建 ReadReplica2。对 MyDBInstance 的更新将复制到 ReadReplica1,然后从 ReadReplica1 复制到 ReadReplica2。一个复制链中不能涉及四个以上的实例。例如,您可以从 MySourceDBInstance 创建 ReadReplica1,再从 ReadReplica1 创建 ReadReplica2,然后从 ReadReplica2 创建 ReadReplica3,但不能再从 ReadReplica3 创建 ReadReplica4。

如果所提升的 MySQL 只读副本进而复制到其他只读副本,则这些只读副本仍有效。设想一个示例,其中 MyDBInstance1 复制到 MyDBInstance2,然后 MyDBInstance2 复制到 MyDBInstance3。如果提升 MyDBInstance2,则将不再从 MyDBInstance1 复制到 MyDBInstance2,但 MyDBInstance2 仍将复制到 MyDBInstance3。

要对 Amazon RDS for MySQL 版本 5.6 和更高版本的只读副本启用自动备份,请先创建只读副本。然后修改只读副本以启用自动备份。

您可以在引用相同源数据库实例的同时,运行多个只读副本创建或删除操作。为此,请保持在每个源实例中 5 个只读副本的限制。

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

准备使用 MyISAM 的 MySQL 数据库实例

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

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

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

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

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

使用 MySQL 配置复制筛选条件

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

以下是复制筛选条件的一些使用案例:

  • 缩减只读副本的大小。使用复制筛选,您可以排除只读副本上不需要的数据库和表。

  • 出于安全原因,将数据库和表从只读副本中排除。

  • 在不同只读副本中为特定使用案例复制不同的数据库和表。例如,您可以使用特定的只读副本进行分析或分片。

  • 对于在不同 Amazon 区域中具有只读副本的数据库实例,要在不同的 Amazon 区域复制不同的数据库或表。

Amazon RDS for MySQL 的复制筛选参数

要配置复制筛选条件,请在只读副本上设置以下复制筛选参数:

  • replicate-do-db –将更改复制到指定的数据库。为只读副本设置此参数时,仅复制参数中指定的数据库。

  • replicate-ignore-db –不将更改复制到指定的数据库。为只读副本设置 replicate-do-db 参数时,不会评估此参数。

  • replicate-do-table –将更改复制到指定的表。为只读副本设置此参数时,仅复制参数中指定的表。此外,设置 replicate-do-dbreplicate-ignore-db 参数时,请确保包含指定表的数据库包含在使用只读副本的复制中。

  • replicate-ignore-table –不将更改复制到指定的表。为只读副本设置 replicate-do-table 参数时,不会评估此参数。

  • replicate-wild-do-table – 根据指定的数据库和表名模式复制表。支持 %_ 通配符。设置 replicate-do-dbreplicate-ignore-db 参数时,请确保包含指定表的数据库包含在使用只读副本的复制中。

  • replicate-wild-ignore-table –不基于指定的数据库和表名模式复制表。支持 %_ 通配符。为只读副本设置 replicate-do-tablereplicate-wild-do-table 参数时,不会评估此参数。

将按这些参数列出的顺序对其进行评估。有关这些参数如何运行的更多信息,请参阅 MySQL 文档:

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

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

源数据库实例的二进制日志记录格式对于复制非常重要,因为它决定了数据更改的记录。binlog_format 参数的设置将决定复制是基于行还是基于语句的复制。有关更多信息,请参阅 设置二进制日志记录格式

注意

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

Amazon RDS for MySQL 的复制筛选限制

以下限制适用于对 Amazon RDS for MySQL 进行复制筛选:

  • 每个复制筛选参数不得超过 2000 个字符。

  • 复制筛选条件中不支持逗号。

  • 不支持用于二进制日志筛选的 MySQL --binlog-do-db--binlog-ignore-db 选项。

  • 复制筛选不支持 XA 事务。

    有关更多信息,请参阅 MySQL 文档中的XA 事务限制

  • Amazon RDS for MySQL 版本 8.0.17 和更高的 8.0 版本、以及版本 5.7.26 及更高的 5.7 版本支持复制筛选。

  • Amazon RDS for MySQL 版本 5.6 不支持复制筛选。

Amazon RDS for MySQL 的复制筛选示例

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

注意

您无法修改默认参数组。如果只读副本使用默认参数组,请创建新的参数组并将其与只读副本关联。有关数据库参数组的更多信息,请参阅 使用数据库参数组

您可以使用 Amazon Web Services Management Console、Amazon CLI 或 RDS API 在参数组中设置参数。有关设置参数的信息,请参阅 修改数据库参数组中的参数。在参数组中设置参数时,与参数组关联的所有数据库实例都使用参数设置。如果在参数组中设置复制筛选参数,请确保参数组仅与只读副本关联。将源数据库实例的复制筛选参数留空。

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

以下示例设置了复制筛选条件:

例 将数据库包含在复制之中

以下示例将 mydb1mydb2 数据库包含在复制之内。

对于 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"}]"

例 将表包含在复制之中

以下示例将数据库 mydb1 中的 table1table2 表包含在复制之中。

对于 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"}]"

例 使用通配符将表包含在复制之中

以下示例将数据库 mydb 中名称以 ordersreturns 开头的表包含在复制之中。

对于 Linux、macOS 或 Unix:

aws rds modify-db-parameter-group \ --db-parameter-group-name myparametergroup \ --parameters "[{"ParameterName": "replicate-wild-do-table", "ParameterValue": "mydb.orders%,mydb.returns%", "ApplyMethod":"immediate"}]"

对于 Windows:

aws rds modify-db-parameter-group ^ --db-parameter-group-name myparametergroup ^ --parameters "[{"ParameterName": "replicate-wild-do-table", "ParameterValue": "mydb.orders%,mydb.returns%", "ApplyMethod":"immediate"}]"

例 转义名称中的通配符

以下示例展示了如何使用转义字符 \ 来转义名称中的通配符。

假设数据库 mydb1 中有多个以 my_table 开头的表名,而且您希望将这些表包含在复制之中。表名包括下划线(下划线也是通配符),因此该示例将表名中的下划线转义。

对于 Linux、macOS 或 Unix:

aws rds modify-db-parameter-group \ --db-parameter-group-name myparametergroup \ --parameters "[{"ParameterName": "replicate-wild-do-table", "ParameterValue": "my\_table%", "ApplyMethod":"immediate"}]"

对于 Windows:

aws rds modify-db-parameter-group ^ --db-parameter-group-name myparametergroup ^ --parameters "[{"ParameterName": "replicate-wild-do-table", "ParameterValue": "my\_table%", "ApplyMethod":"immediate"}]"

例 将数据库排除在复制之外

以下示例将 mydb1mydb2 数据库排除在复制之外。

对于 Linux、macOS 或 Unix:

aws rds modify-db-parameter-group \ --db-parameter-group-name myparametergroup \ --parameters "[{"ParameterName": "replicate-ignore-db", "ParameterValue": "mydb1,mydb2", "ApplyMethod":"immediate"}]"

对于 Windows:

aws rds modify-db-parameter-group ^ --db-parameter-group-name myparametergroup ^ --parameters "[{"ParameterName": "replicate-ignore-db", "ParameterValue": "mydb1,mydb2", "ApplyMethod":"immediate"}]"

例 将表排除在复制之外

以下示例将数据库 mydb1 中的表 table1table2排除在复制之外。

对于 Linux、macOS 或 Unix:

aws rds modify-db-parameter-group \ --db-parameter-group-name myparametergroup \ --parameters "[{"ParameterName": "replicate-ignore-table", "ParameterValue": "mydb1.table1,mydb1.table2", "ApplyMethod":"immediate"}]"

对于 Windows:

aws rds modify-db-parameter-group ^ --db-parameter-group-name myparametergroup ^ --parameters "[{"ParameterName": "replicate-ignore-table", "ParameterValue": "mydb1.table1,mydb1.table2", "ApplyMethod":"immediate"}]"

例 使用通配符将表排除在复制之外

以下示例将数据库 mydb 中名称以 ordersreturns 开头的表排除在复制之外。

对于 Linux、macOS 或 Unix:

aws rds modify-db-parameter-group \ --db-parameter-group-name myparametergroup \ --parameters "[{"ParameterName": "replicate-wild-ignore-table", "ParameterValue": "mydb.orders%,mydb.returns%", "ApplyMethod":"immediate"}]"

对于 Windows:

aws rds modify-db-parameter-group ^ --db-parameter-group-name myparametergroup ^ --parameters "[{"ParameterName": "replicate-wild-ignore-table", "ParameterValue": "mydb.orders%,mydb.returns%", "ApplyMethod":"immediate"}]"

查看只读副本的复制筛选条件

您可以通过以下方式查看只读副本的复制筛选条件:

  • 检查与只读副本关联的参数组中复制筛选参数的设置。

    有关说明,请参阅查看数据库参数组的参数值

  • 在 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 文档中的检查复制状态

    注意

    以前的 MySQL 版本使用的是 SHOW SLAVE STATUS,而不是 SHOW REPLICA STATUS。如果您使用的 MySQL 版本低于 8.0.23,那么请使用 SHOW SLAVE STATUS

使用 MySQL 配置延迟复制

可以使用延迟复制作为灾难恢复策略。使用延迟复制,可指定最短的时间(以秒为单位)以延迟从源到只读副本的复制。如果出现灾难(如意外删除了表),可完成以下步骤以快速从灾难恢复:

注意
  • 在 Amazon RDS for MySQL 5.7 上,支持针对 MySQL 5.7.22 及更高版本的延迟复制。在 Amazon RDS for MySQL 5.6 上,支持针对 MySQL 5.6.40 及更高版本的延迟复制。在 Amazon RDS for MySQL 8.0 上不支持延迟复制。

  • 使用存储过程配置延迟复制。无法使用 Amazon Web Services Management Console、Amazon CLI 或 Amazon RDS API 配置延迟复制。

  • 在 Amazon RDS for MySQL 5.7.23 和更高的 MySQL 5.7 版本中,您可以在延迟复制配置中使用基于全局事务标识符 (GTID) 的复制。如果使用基于 GTID 的复制,请使用 mysql.rds_start_replication_until_gtid 存储过程而不是 mysql.rds_start_replication_until 存储过程。有关基于 GTID 的复制的更多信息,请参阅在 RDS for MySQL 中使用基于 GTID 的复制

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

要为未来通过数据库实例创建的任何只读副本配置延迟复制,请使用 target delay 参数运行 mysql.rds_set_configuration 存储过程。

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

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

  2. 使用 mysql.rds_set_configuration 参数运行 target delay 存储过程。

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

    call mysql.rds_set_configuration('target delay', 3600);
    注意

    运行此存储过程之后,将为使用 Amazon CLI 或 Amazon RDS API 创建的任何只读副本配置延迟指定秒数的复制。

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

要修改现有只读副本的延迟复制,请运行 mysql.rds_set_source_delay 存储过程。

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

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

  2. 使用 mysql.rds_stop_replication 存储过程停止复制。

  3. 运行 mysql.rds_set_source_delay 存储过程。

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

    call mysql.rds_set_source_delay(3600);
  4. 使用 mysql.rds_start_replication 存储过程开始复制。

设置停止复制到只读副本的位置

停止复制到只读副本之后,可使用 mysql.rds_start_replication_until 存储过程开始复制,然后在指定二进制日志文件位置处停止复制。

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

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

  2. 运行 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

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

MySQL 只读副本更新

只读副本旨在支持读取查询,但您可能需要偶尔进行更新。例如,您可能需要添加索引,以优化访问副本的特定类型的查询。您可通过在只读副本的数据库参数组中将 read_only 参数设置为 0 来启用更新。对只读副本禁用只读时要小心,如果只读副本变得与源数据库实例不兼容,会导致出现问题。尽快将 read_only 参数的值更改回 1

多可用区 MySQL 只读副本部署

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

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

注意

要将只读副本创建为多可用区数据库实例,数据库实例必须为 MySQL 5.6 或更高版本。

监控 MySQL 只读副本

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

注意

以前的 MySQL 版本使用的是 SHOW SLAVE STATUS,而不是 SHOW REPLICA STATUS。如果您使用的 MySQL 版本低于 8.0.23,那么请使用 SHOW SLAVE STATUS

MySQL 复制滞后的常见原因如下所示:

  • 网络中断。

  • 对只读副本上有不同索引的表进行写入操作。如果在只读副本上将 read_only 参数设置为 0,则在只读副本变得与源数据库实例不兼容时,复制会中断。对只读副本执行维护任务之后,我们建议您将 read_only 参数调整回 1

  • 使用 MyISAM 等非事务性存储引擎。仅 MySQL 上的 InnoDB 存储引擎支持复制。

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

开始和停止 MySQL 只读副本复制

可通过调用系统存储过程 mysql.rds_stop_replicationmysql.rds_start_replication,在 Amazon RDS 数据库实例上停止再重新开始复制过程。对于长时间运行的操作 (如创建大型索引),在两个 Amazon RDS 实例之间进行复制时可以这样做。在导入或导出数据库时,也需要停止再开始复制。有关更多信息,请参阅将数据导入到 Amazon RDS MySQL 或 MariaDB 数据库实例并减少停机时间使用复制从 MySQL 数据库实例中导出数据

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

排查 MySQL 只读副本问题

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

MySQL 的复制技术是异步的。由于它们是异步的,因此,源数据库实例上偶发的 BinLogDiskUsage 会增多,而只读副本上应有 ReplicaLag。例如,对源数据库实例的大量写入操作可以并行进行。与之对比的是,对只读副本的写入操作使用单个 I/O 线程串行进行,这会导致源实例与只读副本之间存在滞后。有关 MySQL 文档中只读副本的更多信息,请参阅复制实施详细信息

您可通过多种方式来减少对源数据库实例的更新与对只读副本的后续更新之间的滞后,例如:

  • 将只读副本的存储大小和数据库实例类调整到与源数据库实例类似。

  • 确保源数据库实例和只读副本使用的数据库参数组中的参数设置相兼容。有关更多信息和示例,请参阅本部分后面的有关 max_allowed_packet 参数的讨论。

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

可通过查看 Replication Error 字段,检查 MySQL 引擎引发的关联错误的详细信息。还生成指示只读副本状态的事件,包括 RDS-EVENT-0045RDS-EVENT-0046RDS-EVENT-0047。有关这些事件和事件订阅的详细信息,请参阅 使用 Amazon RDS 事件通知。如果返回 MySQL 错误消息,则检查 MySQL 错误消息文档中的错误编号。

一个可导致复制出错的常见问题是只读副本的 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()。有关更多信息,请参阅确定二进制日志记录中的安全和不安全语句

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