使用 Amazon RDS for PostgreSQL 只读副本 - Amazon Relational Database Service

使用 Amazon RDS for PostgreSQL 只读副本

您可以通过向实例添加只读副本来扩展 Amazon RDS for PostgreSQL 数据库实例的读取。与其他 Amazon RDS 数据库引擎一样,RDS for PostgreSQL 使用 PostgreSQL 的本机复制机制来使只读副本与源数据库的更改保持同步。有关只读副本和 Amazon RDS 的一般信息,请参阅使用只读副本

在下文中,您可以找到使用 RDS for PostgreSQL 只读副本的特定信息。

PostgreSQL 只读副本限制

以下是 PostgreSQL 只读副本的限制:

  • PostgreSQL 只读副本是只读的。尽管只读副本不是可写的数据库实例,但您可以将其升级为独立的 RDS for PostgreSQL 数据库实例。不过该过程无法撤消。

  • 如果 RDS for PostgreSQL 数据库实例运行的是 14.1 之前的 PostgreSQL 版本,则无法从另一个只读副本创建只读副本。RDS for PostgreSQL 仅支持在 RDS for PostgreSQL 版本 14.1 版及更高版本上级联只读副本。有关更多信息,请参阅将级联只读副本用于 RDS for PostgreSQL

  • 如果您升级 PostgreSQL 只读副本,它将成为可写的数据库实例。它停止从源数据库实例接收预写日志(WAL)文件,并且已不再是只读实例。您可以像对任何 RDS for PostgreSQL 数据库实例一样从升级的数据库实例创建新只读副本。有关更多信息,请参阅将只读副本提升为独立的数据库实例

  • 如果您从复制链(一系列级联只读副本)中升级 PostgreSQL 只读副本,则任何现有的下游只读副本将继续自动从升级后的实例接收 WAL 文件。有关更多信息,请参阅将级联只读副本用于 RDS for PostgreSQL

  • 如果源数据库实例上未发生任何用户事务,则 PostgreSQL 只读副本将在最迟 5 分钟后报告复制滞后。

  • 您无法为早于 14.1 的 RDS for PostgreSQL 版本的 PostgreSQL 只读副本启用自动备份。仅 RDS for PostgreSQL 14.1 及更高版本支持只读副本的自动备份。对于 RDS for PostgreSQL 13 和更早版本,如果需要只读副本的备份,请从只读副本创建快照。

  • 只读副本不支持时间点故障恢复(PITR)。您只能将 PITR 用于主(写入器)实例,而不能用于只读副本。要了解更多信息,请参阅“将数据库实例还原到指定时间”。

PostgreSQL 只读副本配置

RDS for PostgreSQL 使用 PostgreSQL 本机流式复制来创建源数据库实例的只读副本。此只读副本数据库实例是源数据库实例的异步创建的物理副本。该副本是通过在源数据库实例和只读副本之间传输预写日志(WAL)数据的特殊连接创建。有关更多信息,请参阅 PostgreSQL 文档中的流式复制

在源数据库实例上进行更改时,PostgreSQL 会通过此安全连接异步流式传输数据库更改。您可以通过将 ssl 参数设置为 1,来加密从客户端应用程序到源数据库实例或任何只读副本的通信。有关更多信息,请参阅将 SSL 与 PostgreSQL 数据库实例结合使用

PostgreSQL 使用复制角色执行流式复制。该角色拥有特权,但不能用于修改任何数据。PostgreSQL 使用处理复制的单个过程。

您可以在不影响源数据库实例的操作或用户的情况下创建 PostgreSQL 只读副本。Amazon RDS 为您在源数据库实例和只读副本上设置必要的参数和权限,而不会影响服务。为源数据库实例拍摄快照,该快照用于创建只读副本。如果您在将来某个时间点删除只读副本,则不会发生中断。

您可以从一个源数据库实例创建最多 5 个只读副本。自 RDS for PostgreSQL 14.1 起,您还可以从源数据库实例在链(级联)中创建最多三个级别的只读副本。有关更多信息,请参阅将级联只读副本用于 RDS for PostgreSQL。在所有情况下,源数据库实例都需要配置自动备份。为此,您可以将数据库实例上的备份保留期设置为非 0 值。有关更多信息,请参阅创建只读副本

您可以在与源数据库实例相同的 AWS 区域中为您的 RDS for PostgreSQL 数据库实例创建只读副本。这称为区域内复制。您还可以在与源数据库实例不同的 AWS 区域中创建只读副本。这称为跨区域复制。有关设置跨区域只读副本的更多信息,请参阅在不同的 AWS 区域中创建只读副本。根据 RDS for PostgreSQL 版本,支持区域内和跨区域复制过程的各种机制略有不同,如流式复制如何适用于不同的 RDS for PostgreSQL 版本中所述。

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

如果 Amazon RDS 从一开始就阻止只读副本,它将覆盖只读副本上的任何不兼容参数。例如,假定源数据库实例上的 max_connections 参数值高于只读副本上的此参数值。在这种情况下,Amazon RDS 将只读副本上的参数更新为与源数据库实例上的参数相同的值。

RDS for PostgreSQL 只读副本可以访问通过源数据库实例上的外部数据包装器(FDW)提供的外部数据库。例如,假设您的 RDS for PostgreSQL 数据库实例使用 mysql_fdw 包装器从 RDS for MySQL 访问数据。如果是这样,只读副本也可以访问该数据。其他支持的 FDW 包括 oracle_fdwpostgres_fdwtds_fdw。有关更多信息,请参阅使用 Amazon RDS for PostgreSQL 支持的外部数据包装器

将 RDS for PostgreSQL 只读副本用于多可用区配置

您可从单可用区或多可用区数据库实例中创建只读副本。您可以借助备用副本,使用多可用区部署提高关键数据的持久性和可用性。备用副本是专用的只读副本,可以在源数据库发生故障转移时承担工作负载。您不能使用备用副本来提供读取流量。但是,可以从大流量、多可用区数据库实例创建只读副本以分流只读查询的负载。要了解关于多可用区部署的更多信息,请参阅 多可用区数据库实例部署

如果多可用区部署的源数据库实例故障转移到备用可用区,则关联的只读副本将切换为使用备用可用区(现在为主可用区)作为其复制源。只读副本可能需要重新启动,具体取决于 RDS for PostgreSQL 版本,如下所示:

  • PostgreSQL 13 及更高版本 – 不需要重新启动。只读副本将自动与新的主副本同步。但是,在某些情况下,您的客户端应用程序可能会缓存只读副本的域名服务(DNS)详细信息。如果是这样,请将生存时间(TTL)值设置为小于 30 秒。这样做可以防止只读副本继续留在陈旧的 IP 地址(因此可以防止它与新的主副本同步)。要了解有关此用法和其他最佳实践的更多信息,请参阅Amazon RDS 基本操作指导方针

  • PostgreSQL 12 和所有早期版本 – 只读副本在故障转移到备用副本后自动重新启动,因为备用副本(现为主)具有不同的 IP 地址和不同的实例名称。重启操作会将只读副本与新的主副本同步。

要详细了解失效转移,请参阅Amazon RDS 的故障转移过程。要了解关于只读副本如何在多可用区部署中工作的更多信息,请参阅 使用只读副本

要为只读副本提供失效转移支持,您可以将只读副本创建为多可用区数据库实例,以便 Amazon RDS 在另一个可用区(AZ)中创建备用副本。创建您的只读副本作为多可用区数据库实例与源数据库是否为多可用区数据库实例无关。

将级联只读副本用于 RDS for PostgreSQL

自版本 14.1 开始,RDS for PostgreSQL 支持级联只读副本。使用级联只读副本,您可以扩展读取操作,而不会增加源 RDS for PostgreSQL 数据库实例的开销。源数据库实例不会将 WAL 日志的更新发送到每个只读副本。相反,级联系列中的每个只读副本都将 WAL 日志更新发送到该系列中的下一个只读副本。这将减轻源数据库实例的负担。

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

您可以从源 RDS for PostgreSQL 数据库实例在链中创建最多三个只读副本。例如,假设您具有 RDS for PostgreSQL 14.1 数据库实例 rpg-db-main。您可执行以下操作:

  • rpg-db-main 开始,创建链中的第一个只读副本 read-replica-1

  • 接下来,从 read-replica-1,创建链中的下一个只读副本 read-replica-2

  • 最后,从 read-replica-2,创建链中的第三个只读副本 read-replica-3

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

要使级联只读副本正常工作,请在 RDS for PostgreSQL 上启用自动备份。首先创建只读副本,然后在 RDS for PostgreSQL 数据库实例上启用自动备份。此过程与其他 Amazon RDS 数据库引擎相同。有关更多信息,请参阅创建只读副本

与任何只读副本一样,您可以升级属于级联一部分的只读副本。从只读副本链中升级只读副本将从链中移除该副本。例如,假设您希望将一些工作负载从 rpg-db-main 数据库实例转移到新实例,以便仅供会计部门使用。假设该示例中的链有三个只读副本,您决定升级 read-replica-2。该链受到如下影响:

  • 升级 read-replica-2 会将其从复制链中移除。

    • 现在它是一个完全读/写数据库实例。

    • 它继续复制到 read-replica-3,就像在升级之前那样。

  • 您的 rpg-db-main 继续复制到 read-replica-1

有关升级只读副本的更多信息,请参阅将只读副本提升为独立的数据库实例

流式复制如何适用于不同的 RDS for PostgreSQL 版本

正如PostgreSQL 只读副本配置中讨论的,RDS for PostgreSQL 使用 PostgreSQL 的原生流式复制协议从源数据库实例发送 WAL 数据。它将源 WAL 数据发送到区域内和跨区域只读副本。在 9.4 版中,PostgreSQL 引入了物理复制槽作为复制过程的支持机制。

物理复制槽可防止源数据库实例在所有只读副本使用 WAL 数据之前将其删除。每个只读副本在源数据库实例上都有自己的物理槽。该槽跟踪副本可能需要的最旧 WAL(按逻辑序列号,LSN)。在所有槽和数据库连接都进展到超出给定 WAL(LSN)之后,该 LSN 将成为在下一个检查点移除的候选项。

Amazon RDS 使用 Amazon S3 来归档 WAL 数据。对于区域内只读副本,您可以在必要时使用此归档数据恢复只读副本。例如,当源数据库和只读副本之间的连接由于任何原因中断时,您就可以这么做。

在下表中,您可以找到 PostgreSQL 版本之间以及 RDS for PostgreSQL 使用的区域内和跨区域支持机制之间的差异的摘要。

区域内 跨区域
PostgreSQL 14.1 and higher versions
  • 复制槽

  • Amazon S3 归档

  • 复制槽

PostgreSQL 13 and lower versions
  • Amazon S3 归档

  • 复制槽

有关更多信息,请参阅监控和调整复制过程

了解控制 PostgreSQL 复制的参数

以下参数会影响复制过程,并确定只读副本与源数据库实例保持同步的程度:

max_wal_senders

max_wal_senders 参数指定源数据库实例可以通过流式复制协议同时支持的最大连接数。RDS for PostgreSQL 13 及更高版本的默认值为 20。此参数应设置为略高于实际只读副本数量。如果此参数设置为对只读副本数来说太少,则复制将停止。

有关更多信息,请参阅 PostgreSQL 文档中的 max_wal_senders

wal_keep_segments

wal_keep_segments 指定源数据库实例在 pg_wal 目录中保留的预写日志(WAL)文件的数量。默认设置为 32。

如果 wal_keep_segments 没有针对您的部署设置为足够大的值,只读副本可能远远落后于流式复制停止。如果出现此情况,Amazon RDS 将生成复制错误并开始对只读副本进行恢复。为此,它将重放来自 Amazon S3 的源数据库实例的已归档 WAL 数据。在只读副本赶上进度可继续流式复制之前,该恢复过程将继续。您可以在示例:只读副本如何从复制中断中恢复中看到 PostgreSQL 日志所捕获的这个过程的实际执行情况。

注意

在 PostgreSQL 版本 13 中,wal_keep_segments 参数名为 wal_keep_size。它的目的与 wal_keep_segments 相同,但其默认值以兆字节(MB),而不是文件数为单位(2048MB)。有关更多信息,请参阅 PostgreSQL 文档中 wal_keep_segmentswal_keep_size

max_slot_wal_keep_size

max_slot_wal_keep_size 参数控制 RDS for PostgreSQL 数据库实例保留在 pg_wal 目录中以服务插槽的 WAL 数据量。此参数用于使用复制槽的配置。此参数的默认值为 -1,这意味着对源数据库实例上保留多少 WAL 数据没有限制。有关监控复制槽的信息,请参阅监控 RDS for PostgreSQL 数据库实例的复制槽

有关此参数的更多信息,请参阅 PostgreSQL 文档中的 max_slot_wal_keep_size

每次向只读副本提供数据的 WAL 流中断时,PostgreSQL 都会切换为恢复模式。它使用来自 Amazon S3 的已归档 WAL 数据或使用与复制槽关联的 WAL 数据来恢复只读副本。在此过程完成后,PostgreSQL 会重新建立流式复制。

示例:只读副本如何从复制中断中恢复

在以下示例中,您可以找到演示只读副本恢复过程的日志详细信息。该示例来自与源数据库在同一 AWS 区域中运行 PostgreSQL 版本 12.9 的 RDS for PostgreSQL 数据库实例,因此不使用复制槽。对于运行早于 14.1 版的 PostgreSQL 且具有区域内只读副本的其他 RDS for PostgreSQL 数据库实例,恢复过程相同。

当只读副本与源数据库实例失去联系时,Amazon RDS 会在日志中将问题记录为 FATAL: could not receive data from WAL stream 消息以及 ERROR: requested WAL segment ... has already been removed。如粗体行所示,Amazon RDS 通过重播归档的 WAL 文件来恢复副本。

2014-11-07 19:01:10 UTC::@:[23180]:DEBUG:  switched WAL source from archive to stream after failure 2014-11-07 19:01:10 UTC::@:[11575]:LOG: started streaming WAL from primary at 1A/D3000000 on timeline 1 2014-11-07 19:01:10 UTC::@:[11575]:FATAL: could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000001A000000D3 has already been removed 2014-11-07 19:01:10 UTC::@:[23180]:DEBUG: could not restore file "00000002.history" from archive: return code 0 2014-11-07 19:01:15 UTC::@:[23180]:DEBUG: switched WAL source from stream to archive after failure recovering 000000010000001A000000D3 2014-11-07 19:01:16 UTC::@:[23180]:LOG:  restored log file "000000010000001A000000D3" from archive

当 Amazon RDS 在副本上重放足够多的已归档 WAL 数据以赶上进度时,将再次开始向只读副本流式传输。恢复流式传输时,Amazon RDS 会向日志文件中写入一个类似以下内容的条目。

2014-11-07 19:41:36 UTC::@:[24714]:LOG:started streaming WAL from primary at 1B/B6000000 on timeline 1

监控和调整复制过程

我们强烈建议您定期监控 RDS for PostgreSQL 数据库实例和只读副本。您需要确保只读副本与源数据库实例上的更改同步。当复制过程中断时,Amazon RDS 可以透明地恢复您的只读副本。但是,最好避免出现需要恢复的情况。使用复制槽进行恢复比使用 Amazon S3 归档快,但是任何恢复过程都可能会影响读取性能。

要确定只读副本与源数据库实例的同步程度,您可以执行以下操作:

  • 检查源数据库实例和副本之间的 ReplicaLag 数量。副本滞后是只读副本滞后于其源数据库实例的时间量(以毫秒为单位)。此指标将报告以下查询的结果。

    SELECT extract(epoch from now() - pg_last_xact_replay_timestamp()) AS replica_lag

    副本滞后可指示只读副本与源数据库实例的同步程度。这是源数据库实例和特定只读实例之间的延迟量。副本滞后值较高可能表示源数据库实例使用的数据库实例类或存储类型(或两者)与其只读副本之间不匹配。数据库源实例和所有只读副本的数据库实例类和存储类型应相同。

    副本滞后也可能是间歇性连接问题导致的。您可以通过查看 Amazon RDS ReplicaLag 指标,在 Amazon CloudWatch 中监控复制滞后。若要了解有关 ReplicaLag 和 Amazon RDS 的其他指标的更多信息,请参阅 Amazon RDS 的 Amazon CloudWatch 指标

  • 查看 PostgreSQL 日志了解可用于调整设置的信息。在每个检查点中,PostgreSQL 日志都会捕获回收事务日志文件的数量,如以下示例所示。

    2014-11-07 19:59:35 UTC::@:[26820]:LOG:  checkpoint complete: wrote 376 buffers (0.2%); 0 transaction log file(s) added, 0 removed, 1 recycled; write=35.681 s, sync=0.013 s, total=35.703 s; sync files=10, longest=0.013 s, average=0.001 s

    您可以使用此信息来确定在给定时间段内回收了多少事务文件,然后可以根据需要更改 wal_keep_segments 设置。例如,假设 checkpoint complete 时的 PostgreSQL 日志每隔 5 分钟显示 35 recycled。在本例中,wal_keep_segments 默认值 32 不足以跟上流式传输活动的节奏,因此应增加此参数的值。

  • 使用 Amazon CloudWatch 监控可以预测复制问题的指标。您可以使用 Amazon CloudWatch 检查已收集的指标,而不是直接分析 PostgreSQL 日志。例如,您可以检查 TransactionLogsGeneration 指标的值,以查看源数据库实例生成了多少 WAL 数据。某些情况下,数据库实例上的工作负载可能会生成大量 WAL 数据。如果是这样,您可能需要更改源数据库实例和只读副本的数据库实例类。使用具有高(10Gbps)网络性能的实例类可以减少副本滞后。

监控 RDS for PostgreSQL 数据库实例的复制槽

所有 RDS for PostgreSQL 版本都将复制槽用于跨区域只读副本。RDS for PostgreSQL 14.1 及更高版本将复制槽用于区域内只读副本。区域内只读副本还使用 Amazon S3 来归档 WAL 数据。换句话说,如果您的数据库实例和只读副本运行 PostgreSQL 14.1 或更高版本,则复制槽和 Amazon S3 归档都可用于恢复只读副本。使用复制槽恢复只读副本比从 Amazon S3 归档中恢复快。因此,我们建议您监控复制槽和相关指标。

您可以通过查询 pg_replication_slots 视图来查看 RDS for PostgreSQL 数据库实例上的复制槽,如下所示。

postgres=> SELECT * FROM pg_replication_slots; slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase ---------------------------+--------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+----------- rds_us_west_1_db_555555555 | | physical | | | f | t | 13194 | | | 23/D8000060 | | reserved | | f (1 row)

reservedwal_status 表示插槽持有的 WAL 数据量在 max_wal_size 参数的范围内。换句话说,复制槽的大小正确。其他可能的状态值如下所示:

  • extended – 插槽超过了max_wal_size设置,但 WAL 数据会被保留。

  • unreserved – 插槽不再拥有所有必需的 WAL 数据。其中一些将在下一个检查点移除。

  • lost – 一些必需的 WAL 数据已删除。插槽不再可用。

pg_replication_slots 视图显示了复制插槽的当前状态。要评估复制插槽的性能,您可以使用 Amazon CloudWatch 并监控以下指标:

  • OldestReplicationSlotLag – 列出滞后时间最长的槽,即落后于主副本最远的副本。此滞后可以与只读副本关联,但也可以与连接关联。

  • TransactionLogsDiskUsage:显示 WAL 数据使用了多少存储空间。如果只读副本出现明显滞后,此指标的值可能会大幅增加。

若要了解将 Amazon CloudWatch 及其指标用于 RDS for PostgreSQL 的更多信息,请参阅 使用 Amazon CloudWatch 监控 Amazon RDS 指标。有关监控 RDS for PostgreSQL 数据库实例上的流复制的更多信息,请参阅 AWS数据库博客上的 Amazon RDS PostgreSQL 复制的最佳实践