Amazon Relational Database Service
用户指南 (API 版本 2014-10-31)
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

使用 PostgreSQL 只读副本

一般使用只读副本配置 Amazon RDS 数据库实例之间的复制。有关只读副本的一般信息,请参阅使用 MariaDB、MySQL 和 PostgreSQL 数据库实例的只读副本

此部分包含有关使用 PostgreSQL 上的只读副本的特定信息。

只读副本配置 (PostgreSQL)

Amazon RDS PostgreSQL 9.3.5 和更高版本使用 PostgreSQL 本机流式复制来创建源 (PostgreSQL 术语中的“主”) 数据库实例的只读副本。此只读副本 (PostgreSQL 术语中的“备用”) 数据库实例是主数据库实例异步创建的物理副本。该副本是由在源数据库实例和只读副本 (其中,PostgreSQL 在发生数据库更改时将异步流式处理这些更改) 之间传输提前写入日志 (WAL) 数据的特殊连接创建的。

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

您必须先通过将备份保留期设置为一个非零值来在源数据库实例上启用自动备份,然后数据库实例才能充当源数据库实例。

创建 PostgreSQL 只读副本不需要中断主数据库实例。Amazon RDS 为源数据库实例和只读副本设置所需的参数和权限,而不中断任何服务。将创建源数据库实例的快照,此快照将变为只读副本。在删除只读副本时不会发生中断。

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

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

PostgreSQL 数据库实例使用一个安全连接,可通过同时将源实例和只读副本实例的 ssl 参数设置为 1 来对此安全连接进行加密。

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

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

如果您使用 postgres_fdw 扩展从远程服务器访问数据,则只读副本还可访问远程服务器。有关使用 postgres_fdw 的更多信息,请参阅使用 postgres_fdw 扩展访问外部数据

监控 PostgreSQL 只读副本

对于 PostgreSQL 只读副本,可以通过在 Amazon CloudWatch 中查看 Amazon RDS ReplicaLag 指标来监控复制滞后。ReplicaLag 指标报告 SELECT extract(epoch from now() - pg_last_xact_replay_timestamp()) AS slave_lag 的值。

只读副本限制 (PostgreSQL)

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

  • 每个 PostgreSQL 只读副本是只读的,无法将其设置为可写只读副本。

  • 无法从一个只读副本创建另一个只读副本 (即,无法创建级联只读副本)。

  • 您可将 PostgreSQL 只读副本提升为新的源数据库实例。但只读副本不会自动变为新的源数据库实例。在提升只读副本时,该副本将停止接收 WAL 通信并且不再是只读实例。必须设置任何后续副本,因为提升的只读副本现已成为新的源数据库实例。

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

PostgreSQL 只读副本的复制中断

在几种情况下,PostgreSQL 源数据库实例会意外地中断只读副本的复制。这些情况包括:

  • max_wal_senders 参数设置为一个太小的值,导致无法向只读副本的数目提供足够的数据。此情况会导致复制停止。

  • PostgreSQL 参数 wal_keep_segments 指示保留多少个 WAL 文件以便为只读副本提供数据。 该参数值指定要保留的日志的数量。如果将该参数值设置为一个太小的值,则可能导致只读副本在流式复制停止后大幅滞后。在此情况下,Amazon RDS 将通过重放源数据库实例的已存档 WAL 日志来报告复制错误并开始在只读副本上执行恢复操作。在只读副本赶上进度可继续流式复制之前,该恢复过程将继续。有关更多信息,请参阅 解决 PostgreSQL 只读副本问题

  • 如果源数据库实例终端节点发生更改,则 PostgreSQL 只读副本需要重启。

在向只读副本提供数据的 WAL 流中断时,PostgreSQL 会切换为恢复模式以使用已存档 WAL 文件还原只读副本。在此过程完成后,PostgreSQL 将尝试重新建立流式复制。

解决 PostgreSQL 只读副本问题

PostgreSQL 对跨区域复制使用复制槽,因此,用于解决相同区域复制问题和跨区域的复制问题的过程是不同的。

排查 AWS 区域中的 PostgreSQL 只读副本问题

PostgreSQL 参数 wal_keep_segments,该参数指示保留多少个提前写入日志 (WAL) 文件以便为只读副本提供数据。 该参数值指定要保留的日志的数量。如果将该参数值设置为一个太小的值,则可能导致只读副本在流式复制停止后大幅滞后。在此情况下,Amazon RDS 将通过重放源数据库实例的已存档 WAL 日志来报告复制错误并开始在只读副本上执行恢复操作。在只读副本赶上进度可继续流式复制之前,该恢复过程将继续。

PostgreSQL 只读副本日志将指明 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 文件,以便赶上并允许只读副本再次开始流式处理。此时,PostgreSQL 将恢复流式处理并将与以下内容类似的行写入到日志文件中。

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

可通过查看日志中的检查点信息来确定应保留的 WAL 文件的数量。PostgreSQL 日志在每个检查点显示以下信息。通过查看这些日志语句的“# recycled”事务日志文件,您可了解在某个时间范围内将回收的事务文件的数目,并根据此信息来调整 wal_keep_segments 参数。

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

例如,假定 PostgreSQL 日志显示在 5 分钟内通过“checkpoint completed”日志语句回收了 35 个文件。在这种情况下,我们了解到,利用此使用模式,只读副本在 5 分钟内依赖 35 个事务文件。如果将源数据库实例的 wal_keep_segments 参数值设置为默认值 32,则只读副本将无法在非流式处理状态下保留 5 分钟。

排查跨 AWS 区域的 PostgreSQL 只读副本问题

PostgreSQL (仅版本 9.4.7 和 9.5.2) 使用物理复制槽来管理源数据库实例上的提前写入日志 (WAL) 保留。Amazon RDS 为每个跨区域只读副本实例创建和关联一个物理复制槽。可使用两个 Amazon CloudWatch 指标、Oldest Replication Slot LagTransaction Logs Disk Usage 来查看最滞后的副本(依据接收到的 WAL 数据)的滞后时间和用于 WAL 数据的存储空间。当跨区域只读副本长时间滞后时,Transaction Logs Disk Usage 值会显著增大。

如果数据库实例上的工作负载生成大量 WAL 数据,则您可能需要更改源数据库实例和只读副本的数据库实例类。在这种情况下,您需要将它更改为具有高 (10Gbps) 网络性能的数据库实例类以使副本保持同步。Amazon CloudWatch 指标 Transaction Logs Generation 可帮助您了解工作负载生成 WAL 数据的速率。

要确定跨区域只读副本的状态,您可以在源实例上查询 pg_replication_slots,如以下示例所示:

postgres=# select * from pg_replication_slots; slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn _______________________________________________________________________________________________________________________________________________ rds_us_east_1_db_uzwlholddgpblksce6hgw4nkte | | physical | | | t | 12598 | | | 4E/95000060 (1 row)