在 Amazon Aurora 全局数据库中使用写入转发 - Amazon Aurora
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 Amazon Aurora 全局数据库中使用写入转发

使用写入转发功能,可以减少管理在 Aurora 全局数据库上运行的应用程序所需的终端节点数量。Aurora MySQL 的此功能可使 Aurora 全局数据库中的辅助集群将执行写入操作的 SQL 语句转发到主集群。主集群会更新源,然后将产生的更改传播回所有辅助 AWS 区域。

写入转发配置可让您不必实施自己的机制以将写入操作从辅助 AWS 区域发送到主区域。Aurora 可处理跨区域网络设置。Aurora 还可传输每个语句的所有必要的会话和事务上下文。始终首先在主集群上更改数据,然后复制到 Aurora 全局数据库中的辅助集群。这样,主集群成为所有数据的真实来源并始终拥有所有数据的最新副本。

注意

写入转发需要 2.08.1 或更高的 Aurora MySQL 版本。

启用写入转发

默认情况下,在将辅助集群添加到 Aurora 全局数据库时不启用写入转发。

要使用 AWS 管理控制台启用写入转发,请在对全局数据库执行添加区域操作时选择启用只读副本写入转发选项。对于现有辅助集群,修改集群以使用启用只读副本写入转发选项。要关闭写入转发,请在添加区域或修改辅助集群时清除启用只读副本写入转发复选框。

要使用 AWS CLI 启用写入转发,请使用 --enable-global-write-forwarding 选项。当您使用 create-db-cluster 命令创建新的辅助集群时,此选项将起作用。当您使用 modify-db-cluster 命令修改现有辅助集群时,它也可以起作用。它要求全局数据库使用支持写入转发的 Aurora 版本。您可以通过对这些相同的 CLI 命令使用 --no-enable-global-write-forwarding 选项来关闭写入转发。

要使用 Amazon RDS API 启用写入转发,请将 EnableGlobalWriteForwarding 参数设置为 true。当您使用 CreateDBCluster 操作创建新的辅助集群时,此参数起作用。当您使用 ModifyDBCluster 操作修改现有辅助集群时,它也起作用。它要求全局数据库使用支持写入转发的 Aurora 版本。您可以通过将 EnableGlobalWriteForwarding 参数设置为 false 来关闭写入转发。

注意

要使数据库会话利用写入转发,请确保您还为 aurora_replica_read_consistency 配置参数指定设置。在使用写入转发功能的每个会话中执行此操作。有关此参数的信息,请参阅写入转发的隔离和一致性

以下 CLI 示例说明如何可以在启用或禁用写入转发的情况下设置 Aurora 全局数据库。突出显示的项表示在为 Aurora 全局数据库设置基础设施时务必指定且保持一致的命令和选项。

以下示例创建启用写入转发的 Aurora 全局数据库、主集群和辅助集群。将用户名、密码以及主要和辅助 AWS 区域替换为您自己选择的内容。

# Create overall global database. aws rds create-global-cluster --global-cluster-identifier write-forwarding-test \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.08.1 \ --region us-east-1 # Create primary cluster, in the same AWS Region as the global database. aws rds create-db-cluster --global-cluster-identifier write-forwarding-test \ --db-cluster-identifier write-forwarding-test-cluster-1 \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.08.1 \ --master-username my_user_name --master-user-password my_password \ --region us-east-1 aws rds create-db-instance --db-cluster-identifier write-forwarding-test-cluster-1 \ --db-instance-identifier write-forwarding-test-cluster-1-instance-1 \ --db-instance-class db.r5.large \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.08.1 \ --region us-east-1 aws rds create-db-instance --db-cluster-identifier write-forwarding-test-cluster-1 \ --db-instance-identifier write-forwarding-test-cluster-1-instance-2 \ --db-instance-class db.r5.large \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.08.1 \ --region us-east-1 # Create secondary cluster, in a different AWS Region than the global database, # with write forwarding enabled. aws rds create-db-cluster --global-cluster-identifier write-forwarding-test \ --db-cluster-identifier write-forwarding-test-cluster-2 \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.08.1 \ --region us-east-2 \ --enable-global-write-forwarding aws rds create-db-instance --db-cluster-identifier write-forwarding-test-cluster-2 \ --db-instance-identifier write-forwarding-test-cluster-2-instance-1 \ --db-instance-class db.r5.large \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.08.1 \ --region us-east-2 aws rds create-db-instance --db-cluster-identifier write-forwarding-test-cluster-2 \ --db-instance-identifier write-forwarding-test-cluster-2-instance-2 \ --db-instance-class db.r5.large \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.08.1 \ --region us-east-2

以下示例从上一个示例继续。它创建一个未启用写入转发的辅助集群,然后启用写入转发。完成此示例后,全局数据库中的所有辅助集群都启用了写入转发功能。

# Create secondary cluster, in a different AWS Region than the global database, # without write forwarding enabled. aws rds create-db-cluster --global-cluster-identifier write-forwarding-test \ --db-cluster-identifier write-forwarding-test-cluster-2 \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.08.1 \ --region us-west-1 aws rds create-db-instance --db-cluster-identifier write-forwarding-test-cluster-2 \ --db-instance-identifier write-forwarding-test-cluster-2-instance-1 \ --db-instance-class db.r5.large \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.08.1 \ --region us-west-1 aws rds create-db-instance --db-cluster-identifier write-forwarding-test-cluster-2 \ --db-instance-identifier write-forwarding-test-cluster-2-instance-2 \ --db-instance-class db.r5.large \ --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.08.1 \ --region us-west-1 aws rds modify-db-cluster --db-cluster-identifier write-forwarding-test-cluster-2 \ --region us-east-2 \ --enable-global-write-forwarding

检查辅助集群是否启用了写入转发

要确定是否可以使用辅助集群中的写入转发,可以检查集群是否具有属性 "GlobalWriteForwardingStatus": "enabled"

在 AWS 管理控制台中,您可以在集群的详细信息页面的配置选项卡上看到 Read replica write forwarding。要查看所有集群的全局写入转发设置的状态,请运行以下 AWS CLI 命令。

辅助集群显示值 "enabled""disabled",以指示写入转发是打开还是关闭。null 的值表示写入转发对该集群不可用。集群不是全局数据库的一部分,或者是主集群而不是辅助集群。如果写入转发处于打开或关闭的过程中,则该值也可能是 "enabling""disabling"

aws rds describe-db-clusters --query '*[].{DBClusterIdentifier:DBClusterIdentifier,GlobalWriteForwardingStatus:GlobalWriteForwardingStatus}' [ { "GlobalWriteForwardingStatus": "enabled", "DBClusterIdentifier": "aurora-write-forwarding-test-replica-1" }, { "GlobalWriteForwardingStatus": "disabled", "DBClusterIdentifier": "aurora-write-forwarding-test-replica-2" }, { "GlobalWriteForwardingStatus": null, "DBClusterIdentifier": "non-global-cluster" } ]

要查找启用了全局写入转发功能的所有辅助集群,请运行以下命令。此命令还会返回集群的读取器终端节点。在 Aurora 全局数据库中使用从辅助集群到主集群的写入转发时,可以使用辅助集群的读取器终端节点。

aws rds describe-db-clusters --query 'DBClusters[].{DBClusterIdentifier:DBClusterIdentifier,GlobalWriteForwardingStatus:GlobalWriteForwardingStatus,ReaderEndpoint:ReaderEndpoint} | [?GlobalWriteForwardingStatus == `enabled`]' [ { "GlobalWriteForwardingStatus": "enabled", "ReaderEndpoint": "aurora-write-forwarding-test-replica-1.cluster-ro-cnpexample.us-west-2.rds.amazonaws.com", "DBClusterIdentifier": "aurora-write-forwarding-test-replica-1" } ]

应用程序和 SQL 与写入转发的兼容性

在具有写入转发的全局数据库中使用某些语句时,不允许这些语句或它们可能产生过时的结果。因此,默认情况下,辅助集群的 EnableGlobalWriteForwarding 设置处于关闭状态。在启用它之前,请检查以确保您的应用程序代码不受任何这些限制的影响。

您可以将以下类型的 SQL 语句与写入转发一起使用:

  • 数据操作语言 (DML) 语句,如 INSERTDELETEUPDATE。对于您可以与写入转发一起使用的这些语句的属性存在一些限制,如下所述。

  • SELECT ... LOCK IN SHARE MODESELECT FOR UPDATE 语句。

  • PREPAREEXECUTE 语句。

以下限制适用于与写入转发一起使用的 SQL 语句。在某些情况下,您可以对在集群级别启用写入转发的辅助集群使用语句。如果 aurora_replica_read_consistency 配置参数未在会话中打开写入转发,则此方法可用。当由于写入转发而不允许使用语句时,尝试使用语句会导致以下格式的错误消息。

ERROR 1235 (42000): This version of MySQL doesn't yet support 'operation with write forwarding'.
数据定义语言 (DDL)

连接到主集群以运行此类语句。

使用临时表中的数据更新永久表

您可以在启用写入转发的辅助集群上使用临时表。但是,如果语句引用临时表,则不能使用 DML 语句来修改永久表。例如,您不能使用从临时表中获取数据的 INSERT ... SELECT 语句。临时表存在于辅助集群上,当该语句在主集群上运行时不可用。

XA 事务

在会话内打开写入转发时,不能在辅助集群上使用以下语句。您可以在未启用写入转发的辅助集群上使用这些语句,或者在 aurora_replica_read_consistency 设置为空的会话中使用这些语句。在会话内启用写入转发之前,请检查您的代码是否使用这些语句。

XA {START|BEGIN} xid [JOIN|RESUME] XA END xid [SUSPEND [FOR MIGRATE]] XA PREPARE xid XA COMMIT xid [ONE PHASE] XA ROLLBACK xid XA RECOVER [CONVERT XID]
永久表的 LOAD 语句

您不能在启用写入转发的辅助集群上使用以下语句。

LOAD DATA INFILE 'data.txt' INTO TABLE t1; LOAD XML LOCAL INFILE 'test.xml' INTO TABLE t1;

您可以将数据加载到辅助集群上的临时表中。但是,请确保您仅在主集群上运行任何引用永久表的 LOAD 语句。

插件语句

您不能在启用写入转发的辅助集群上使用以下语句。

INSTALL PLUGIN example SONAME 'ha_example.so'; UNINSTALL PLUGIN example;
SAVEPOINT 语句

在会话内打开写入转发时,不能在辅助集群上使用以下语句。您可以在未启用写入转发的辅助集群上使用这些语句,或者在 aurora_replica_read_consistency 设置为空白的会话中使用这些语句。在会话内启用写入转发之前,请检查您的代码是否使用这些语句。

SAVEPOINT t1_save; ROLLBACK TO SAVEPOINT t1_save; RELEASE SAVEPOINT t1_save;

写入转发的隔离和一致性

在使用写入转发的会话中,您只能使用 REPEATABLE READ 隔离级别。尽管您也可以将 READ COMMITTED 隔离级别用于辅助 AWS 区域中的只读集群,但该隔离级别不适用于写入转发。有关 REPEATABLE READREAD COMMITTED 隔离级别的信息,请参阅 Aurora MySQL 隔离级别

您可以控制辅助集群上的读取一致性程度。读取一致性级别确定辅助集群在每次读取操作之前要等待多少时间,以确保从主集群复制某些或所有更改。您可以调整读取一致性级别,以确保会话中的所有转发的写入操作在辅助集群中可见,然后再进行任何后续查询。您还可以使用此设置来确保辅助集群上的查询始终看到主集群中的最新更新,即使是由其他会话或其他集群提交的更新。要为应用程序指定此类行为,请为会话级别参数 aurora_replica_read_consistency 选择一个值。

重要

确保您在使用写入转发的每个会话中设置 aurora_replica_read_consistency 参数。否则,Aurora 不会为该会话启用写入转发。此参数的默认值为空。要使其生效,请选择一个特定值。aurora_replica_read_consistency 参数仅对启用写入转发的辅助集群产生影响。

对于 aurora_replica_read_consistency 参数,您可以指定值 EVENTUALSESSIONGLOBAL

随着您提高一致性级别,您的应用程序会花更多时间等待在 AWS 区域之间传播更改。您可以在快速响应时间与确保在运行查询之前在其他位置进行的更改完全可用之间选择平衡。

将读取一致性设置为 EVENTUAL 后,使用写入转发的辅助 AWS 区域中的查询可能会看到由于复制滞后而稍微过时的数据。在对主区域执行写入操作并将其复制到当前区域之前,看不到同一会话中写入操作的结果。查询不会等待更新的结果可用。因此,它可能会检索较旧的数据或更新的数据,具体取决于语句的时间和复制滞后量。

将读取一致性设置为 SESSION 后,辅助 AWS 区域中使用写入转发的所有查询都会看到在该会话中所做的所有更改的结果。无论事务是否已提交,这些更改都是可见的。如有必要,查询将等待转发的写入操作的结果复制到当前区域。它不会等待在其他区域或当前区域内的其他会话中执行的写入操作的更新结果。

将读取一致性设置为 GLOBAL 后,辅助 AWS 区域中的会话会看到该会话所做的更改。它还可以查看来自主 AWS 区域和其他辅助 AWS 区域的所有已提交的更改。每个查询可能会等待一段时间,该时间取决于会话滞后量。从查询开始时,辅助集群与来自主集群的所有已提交数据处于最新状态时,查询将继续进行。

有关写入转发涉及的所有参数的更多信息,请参阅 写入转发的配置参数

使用写入转发的示例

在此示例中,主集群位于 AWS 区域 美国东部(弗吉尼亚北部) 中。辅助集群位于 AWS 区域 美国东部(俄亥俄州) 中。该示例显示运行 INSERT 语句后跟 SELECT 语句的效果。根据 aurora_replica_read_consistency 设置的值,结果可能会因语句的时间而异。为了实现更高的一致性,您可以在发布 SELECT 语句之前稍等一下,或者 Aurora 可以自动等待结果完成复制,然后再继续执行 SELECT

在此示例中,如果读取一致性设置为 eventual,则运行一条 INSERT 语句后紧接着运行一条 SELECT 语句,仍会返回反映在插入新行之前行数的 COUNT(*) 值。稍后再次运行 SELECT 会返回更新的行计数。这些 SELECT 语句不会进行任何等待。

mysql> set aurora_replica_read_consistency = 'eventual'; mysql> select count(*) from t1; +----------+ | count(*) | +----------+ | 5 | +----------+ 1 row in set (0.00 sec) mysql> insert into t1 values (6); select count(*) from t1; +----------+ | count(*) | +----------+ | 5 | +----------+ 1 row in set (0.00 sec) mysql> select count(*) from t1; +----------+ | count(*) | +----------+ | 6 | +----------+ 1 row in set (0.00 sec)

如果读取一致性设置为 session,则紧随 INSERT 后的一条 SELECT 语句会等到来自 INSERT 语句的更改可见。后续 SELECT 语句不会进行任何等待。

mysql> set aurora_replica_read_consistency = 'session'; mysql> select count(*) from t1; +----------+ | count(*) | +----------+ | 6 | +----------+ 1 row in set (0.01 sec) mysql> insert into t1 values (6); select count(*) from t1; select count(*) from t1; Query OK, 1 row affected (0.08 sec) +----------+ | count(*) | +----------+ | 7 | +----------+ 1 row in set (0.37 sec) +----------+ | count(*) | +----------+ | 7 | +----------+ 1 row in set (0.00 sec)

当读取一致性设置仍设置为 session,如果在执行一条 INSERT 语句后引入简短的等待,则会使更新的行计数在下一条 SELECT 语句运行时可用。

mysql> insert into t1 values (6); select sleep(2); select count(*) from t1; Query OK, 1 row affected (0.07 sec) +----------+ | sleep(2) | +----------+ | 0 | +----------+ 1 row in set (2.01 sec) +----------+ | count(*) | +----------+ | 8 | +----------+ 1 row in set (0.00 sec)

如果读取一致性设置为 global 时,每个 SELECT 语句将等待,以确保在执行该查询之前,该语句开始时的所有数据更改均可见。每个 SELECT 语句的等待量会有所不同,具体取决于主集群和辅助集群之间的复制滞后量。

mysql> set aurora_replica_read_consistency = 'global'; mysql> select count(*) from t1; +----------+ | count(*) | +----------+ | 8 | +----------+ 1 row in set (0.75 sec) mysql> select count(*) from t1; +----------+ | count(*) | +----------+ | 8 | +----------+ 1 row in set (0.37 sec) mysql> select count(*) from t1; +----------+ | count(*) | +----------+ | 8 | +----------+ 1 row in set (0.66 sec)

运行带写入转发的多部分语句

DML 语句可能由多个部分组成,如 INSERT ... SELECT 语句或 DELETE ... WHERE 语句。在这种情况下,整个语句将转发到主集群并在此处运行。

使用写入转发的事务

事务是否转发到主集群取决于事务的访问模式。您可以使用 SET TRANSACTION 语句或 START TRANSACTION 语句指定事务的访问模式。您还可以通过更改 Aurora MySQL 会话变量 tx_read_only 的值来指定事务访问模式。只有在连接到启用了写入转发的辅助集群时,才能更改此会话值。

如果长时间运行的事务在很长一段时间内没有发出任何语句,则可能会超过空闲超时期限。此时段的默认值为一分钟。您最多可以将其增加到一天。超过空闲超时的事务将被主集群取消。您提交的下一个后续语句会收到超时错误。然后 Aurora 回滚事务。

在写入转发变得不可用的其他情况下,可能会发生此类错误。例如,如果重新启动主集群或关闭写入转发配置设置,则 Aurora 取消使用写入转发的任何事务。

写入转发的配置参数

Aurora 集群参数组包含写入转发功能的一些新设置。由于这些是集群参数,因此每个集群中的所有数据库实例对于这些变量具有相同的值。要控制来自辅助集群的传入写入请求,请在主集群上使用以下设置:

  • aurora_fwd_master_max_connections_pct:可以在写入器数据库实例上用于处理从读取器转发的查询的数据库连接的上限。它表示为主集群中写入器数据库实例的 max_connections 设置的百分比。例如,如果 max_connections 是 800,而 aurora_fwd_master_max_connections_pct 是 10,则写入器最多允许 80 个同时转发会话。这些连接来自由 max_connections 设置管理的同一连接池。

    当一个或多个辅助集群启用了写入转发时,此设置仅适用于主集群。如果减小该值,不会影响现有连接。Aurora 尝试从辅助集群创建新连接时,会考虑设置的新值。默认值为 10,表示 max_connections 值的 10%。如果在任何辅助集群上启用查询转发,则此设置必须具有非零值才能成功地从辅助集群执行写入操作。如果值为零,则写入操作会收到错误代码 ER_CON_COUNT_ERROR 以及消息 Not enough connections on master to handle your request

  • aurora_fwd_master_idle_timeout:主集群在关闭连接之前从辅助集群转发的连接上等待某个活动的秒数。如果会话在此期间之后仍处于空闲状态,则 Aurora 取消会话。

以下新参数是会话级别参数:

  • aurora_replica_read_consistency:启用写入转发的值。要发生写入转发,请在每个会话中设置它。有关更多信息,请参阅 写入转发的隔离和一致性

    指定读取一致性级别。可以指定以下值之一:

    • EVENTUAL

    • SESSION

    • GLOBAL

    有关一致性级别含义的信息,请参阅 写入转发的隔离和一致性

    以下规则适用于此参数:

    • 这是一个会话级别的参数。默认值是 ''(空)。

    • 仅当 aurora_replica_read_consistency 设置为 EVENTUALSESSIONGLOBAL 时,写入转发才可用。此参数仅适用于启用了写入转发且位于 Aurora 全局数据库中的辅助集群的读取器实例。

    • 您不能在多语句事务内部设置此变量(如果为空)或取消设置(如果已设置)。但是,在此类事务期间,您可以将其从一个有效值(EVENTUALSESSIONGLOBAL)更改为另一个有效值(EVENTUALSESSIONGLOBAL)。

    • 当辅助集群上未启用写入转发时,变量不能为 SET

    • 在主集群上设置会话变量没有任何效果。如果您尝试修改主集群上的此变量,您会收到错误。

下表显示这些参数的详细信息。

名称 范围 类型 默认值 有效值
aurora_replica_read_consistency Session 枚举 '' EVENTUALSESSIONGLOBAL
aurora_fwd_master_max_connections_pct 服务全球 无符号长整数 10 0–90
aurora_fwd_master_idle_timeout 服务全球 无符号整数 60 1–86,400

写入转发的 Amazon CloudWatch 指标

在一个或多个辅助集群上使用写入转发时,以下 Amazon CloudWatch 指标适用于主集群。这些指标均在主集群中的写入器数据库实例上进行测量。

指标 Aurora MySQL 状态变量 描述 单位
ForwardingMasterDMLLatency 在写入器数据库实例上处理每个转发的 DML 语句的平均时间。它不包括辅助集群转发写请求的时间。它也不包括将更改复制回辅助集群的时间。 毫秒
ForwardingMasterOpenSessions Aurora_fwd_master_open_sessions 写入器数据库实例上的转发会话数。 计数
ForwardingMasterDMLThroughput 此写入器数据库实例每秒处理的转发 DML 语句数。 每秒计数
Aurora_fwd_master_dml_stmt_duration 转发到此写入器数据库实例的 DML 语句的总持续时间。 微秒
Aurora_fwd_master_dml_stmt_count 转发到此写入器数据库实例的 DML 语句总数。
Aurora_fwd_master_select_stmt_duration 转发到此写入器数据库实例的 SELECT 语句的总持续时间。 微秒
Aurora_fwd_master_select_stmt_count 转发到此写入器数据库实例的 SELECT 语句总数。

以下 CloudWatch 指标适用于每个辅助集群。这些指标在启用写入转发的辅助集群中的每个读取器数据库实例上进行测量。

指标 Aurora MySQL 状态变量 描述 单位
ForwardingReplicaDMLLatency 副本上转发 DML 的平均响应时间(以毫秒为单位)。 毫秒
ForwardingReplicaReadWaitLatency 读取器数据库实例上的 SELECT 语句等待追赶主集群的平均等待时间(以毫秒为单位)。读取器数据库实例在处理查询之前等待的程度取决于 aurora_replica_read_consistency 设置。 毫秒
ForwardingReplicaDMLThroughput 每秒处理的转发 DML 语句数。 每秒计数
ForwardingReplicaReadWaitThroughput 在启用写转发的会话中,每秒处理的 SELECT 语句数。 每秒计数
ForwardingReplicaOpenSessions Aurora_fwd_replica_open_sessions 在读取器数据库实例上使用写入转发的会话数。 计数
Aurora_fwd_replica_dml_stmt_count 从此读取器数据库实例转发的 DML 语句总数。
Aurora_fwd_replica_dml_stmt_duration 从此读取器数据库实例转发的 DML 语句的总持续时间。 微秒
Aurora_fwd_replica_select_stmt_duration 从此读取器数据库实例转发的 SELECT 语句的总持续时间。 微秒
Aurora_fwd_replica_select_stmt_count 从此读取器数据库实例转发的 SELECT 语句总数。
Aurora_fwd_replica_read_wait_duration 由于此读取器数据库实例上的读取一致性设置而导致的总等待持续时间。 微秒
Aurora_fwd_replica_read_wait_count 此读取器数据库实例上的写入后读取等待的总数。
Aurora_fwd_replica_errors_session_limit 由于错误条件 master fullToo many forwarded statements in progress 而被主集群拒绝的会话数。