使用 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 只读副本的特定信息。

只读副本上的逻辑解码

RDS for PostgreSQL 支持使用 PostgreSQL 16.1 从备用数据库实例进行逻辑复制。这允许您从只读备用数据库实例创建逻辑解码,从而减少主数据库实例上的负载。对于需要在多个系统之间同步数据的应用程序,您可以实现更高的可用性。此功能可提高数据仓库和数据分析的性能。

此外,给定备用数据库实例上的复制插槽会持续将该备用数据库实例提升为主数据库实例。这意味着,如果主数据库实例发生失效转移或将备用数据库实例提升为新的主数据库实例,则复制插槽将持续存在,以前的备用数据库实例订阅用户不会受到影响。

在只读副本上创建逻辑解码
  1. 开启逻辑复制 - 要在备用数据库实例上创建逻辑解码,您必须在源数据库实例及其物理副本上启用逻辑复制。有关更多信息,请参阅 PostgreSQL 只读副本配置

    • 为新创建的 RDS for PostgreSQL 数据库实例启用逻辑复制 – 创建新的数据库自定义参数组,并将静态参数 rds.logical_replication 设置为 1。然后,将此数据库参数组与源数据库实例及其物理只读副本相关联。有关更多信息,请参阅 在 Amazon RDS 中将数据库参数组与数据库实例关联

    • 为现有 RDS for PostgreSQL 数据库实例开启逻辑复制 – 修改源数据库实例及其物理只读副本的数据库自定义参数组,以将静态参数 rds.logical_replication 设置为 1。有关更多信息,请参阅 在 Amazon RDS 中修改数据库参数组中的参数

    注意

    必须重启数据库实例才能应用这些参数更改。

    您可以使用以下查询来验证源数据库实例及其物理只读副本上的 wal_levelrds.logical_replication 值。

    Postgres=>SELECT name,setting FROM pg_settings WHERE name IN ('wal_level','rds.logical_replication'); name | setting -------------------------+--------- rds.logical_replication | on wal_level | logical (2 rows)
  2. 在源数据库中创建表 – 连接到源数据库实例中的数据库。有关更多信息,请参阅 连接到运行 PostgreSQL 数据库引擎的数据库实例

    使用以下查询在源数据库中创建表并插入值:

    Postgres=>CREATE TABLE LR_test (a int PRIMARY KEY); CREATE TABLE
    Postgres=>INSERT INTO LR_test VALUES (generate_series(1,10000)); INSERT 0 10000
  3. 为源表创建发布 - 使用以下查询为源数据库实例上的表创建发布。

    Postgres=>CREATE PUBLICATION testpub FOR TABLE LR_test; CREATE PUBLICATION

    使用 SELECT 查询来验证在源数据库实例和物理只读副本实例上创建的发布的详细信息。

    Postgres=>SELECT * from pg_publication; oid | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate | pubviaroot -------+---------+----------+--------------+-----------+-----------+-----------+-------------+------------ 16429 | testpub | 16413 | f | t | t | t | t | f (1 row)
  4. 从逻辑副本实例创建订阅 – 创建另一个 RDS for PostgreSQL 数据库实例作为逻辑副本实例。确保 VPC 设置正确,以确保此逻辑副本实例可以访问物理只读副本实例。有关更多信息,请参阅 Amazon VPC 和 Amazon RDS。如果您的源数据库实例处于空闲状态,则可能会出现连接问题,并且主数据库实例不会将数据发送到备用数据库实例。

    Postgres=>CREATE SUBSCRIPTION testsub CONNECTION 'host=Physical replica host name port=port dbname=source_db_name user=user password=password' PUBLICATION testpub; NOTICE: created replication slot "testsub" on publisher CREATE SUBSCRIPTION
    Postgres=>CREATE TABLE LR_test (a int PRIMARY KEY); CREATE TABLE

    使用 SELECT 查询来验证逻辑副本实例上的订阅详细信息。

    Postgres=>SELECT oid,subname,subenabled,subslotname,subpublications FROM pg_subscription; oid | subname | subenabled | subslotname | subpublications -------+---------+------------+-------------+----------------- 16429 | testsub | t | testsub | {testpub} (1 row) postgres=> select count(*) from LR_test; count ------- 10000 (1 row)
  5. 检查逻辑复制插槽状态 - 您只能看到源数据库实例上的物理复制插槽。

    Postgres=>select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots; slot_name | slot_type | confirmed_flush_lsn ---------------------------------------------+-----------+--------------------- rds_us_west_2_db_dhqfsmo5wbbjqrn3m6b6ivdhu4 | physical | (1 row)

    但是,在您的只读副本实例上,您可以看到逻辑复制插槽和 confirmed_flush_lsn 值会随着应用程序主动使用逻辑更改而发生变化。

    Postgres=>select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots; slot_name | slot_type | confirmed_flush_lsn -----------+-----------+--------------------- testsub | logical | 0/500002F0 (1 row)
    Postgres=>select slot_name, slot_type, confirmed_flush_lsn from pg_replication_slots; slot_name | slot_type | confirmed_flush_lsn -----------+-----------+--------------------- testsub | logical | 0/5413F5C0 (1 row)

PostgreSQL 只读副本限制

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

注意

运行 PostgreSQL 版本 12 及更早版本的 RDS for PostgreSQL 多可用区和单可用区数据库实例的只读副本会在 60 到 90 天的维护时段内自动重启以应用密码轮换。如果在安排的重启之前从副本到源的连接中断,则实例仍将重启以继续复制。

  • 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 只读副本会报告长达五分钟的复制滞后。副本滞后的计算公式为 currentTime - lastCommitedTransactionTimestamp,这意味着,当未处理任何事务时,副本滞后值会在一段时间内增加,直到预写日志(WAL)分段切换。默认情况下,RDS for PostgreSQL 每 5 分钟切换一次 WAL 分段,这会导致事务记录以及报告的滞后减少。

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

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

PostgreSQL 只读副本配置

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

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

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

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

您可以从同一区域内的一个源数据库实例创建最多 15 个只读副本。自 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 只读副本用于多可用区配置

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

如果多可用区部署的源数据库实例故障转移到备用可用区,则关联的只读副本将切换为使用备用可用区(现在为主可用区)作为其复制源。只读副本可能需要重新启动,具体取决于 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 在第一复制级别为每个源数据库实例支持 15 个只读副本,在第二和第三复制级别为每个源数据库实例支持 5 个只读副本。

使用 RDS for PostgreSQL 创建跨区域级联只读副本

RDS for PostgreSQL 支持跨区域级联只读副本。您可以从源数据库实例创建跨区域副本,然后从该实例创建同区域副本。您也可以从源数据库实例创建同区域副本,然后从该实例创建跨区域副本。

创建跨区域副本,然后创建同区域副本

您可以使用版本 14.1 或更高版本的 RDS for PostgreSQL 数据库实例 rpg-db-main 执行以下操作:

  1. rpg-db-main(US-EAST-1)开始,在链中创建第一个跨区域只读副本 read-replica-1(US-WEST-2)。

  2. 使用第一个跨区域 read-replica-1(US-WEST-2),在链中创建第二个只读副本 read-replica-2(US-WEST-2)。

  3. 使用 read-replica-2 在链中创建第三个只读副本 read-replica-3(US-WEST-2)。

创建同区域副本,然后创建跨区域副本

您可以使用版本 14.1 或更高版本的 RDS for PostgreSQL 数据库实例 rpg-db-main 执行以下操作:

  1. rpg-db-main(US-EAST-1)开始,在链中创建第一个只读副本 read-replica-1(US-EAST-1)。

  2. 使用 read-replica-1(US-EAST-1),在链中创建第一个跨区域只读副本 read-replica-2(US-WEST-2)。

  3. 使用 read-replica-2 (US-WEST-2) 在链中创建第三个只读副本 read-replica-3(US-WEST-2)。

有关创建跨区域只读副本的限制
  • 数据库副本的跨区域级联链最多可跨两个区域以及包含四个级别。这四个级别包括数据库源和三个只读副本。

使用级联只读副本所带来的好处
  • 提高了读取可扩展性:通过将读取查询分布到多个副本,级联复制有助于实现负载平衡。这将减轻写入器数据库的压力,从而提高性能,尤其是在读取密集型应用程序中。

  • 地理分布;级联副本可位于不同的地理位置。这将减少远离主数据库的用户的延迟,并提供本地只读副本,从而提升性能和用户体验。

  • 高可用性和灾难恢复:如果主服务器发生故障,可以将副本提升为主服务器,从而确保连续性。级联复制可提供多层失效转移选项来进一步增强此能力,从而提高系统的整体韧性。

  • 灵活性和模块化增长:着系统规模的增长,可以在不同的级别添加新副本,而无需对主数据库进行重大重新配置。此模块化方法可实现复制设置的可扩展且可管理的增长。

有关使用复制的好处的更多信息,请参阅 About replication in Cloud SQL

使用跨区域只读副本的最佳实践
  • 在提升一个副本之前,请创建其他副本。这既能节省时间,又能有效处理工作负载。

流式复制如何适用于不同的 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 及更高版本
  • 复制槽

  • Amazon S3 归档

  • 复制槽

PostgreSQL 13 及更低版本
  • 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

设置控制共享内存的参数

您设置的参数确定了用于跟踪事务 ID、锁和已准备事务的共享内存的大小。备用实例的共享内存结构必须等于或大于主实例的共享内存结构。这样可以确保前者在恢复过程中不会耗尽共享内存。如果副本上的参数值小于主实例上的参数值,Amazon RDS 将自动调整副本参数并重启引擎。

受影响的参数有:

  • max_connections

  • max_worker_processes

  • max_wal_senders

  • max_prepared_transactions

  • max_locks_per_transaction

为避免由于内存不足而导致副本 RDS 重启,我们建议将参数更改作为滚动重启应用于每个副本。在设置参数时,必须应用以下规则:

  • 增加参数值:

    • 您应始终先增加所有只读副本的参数值,然后对所有副本执行滚动重启。然后,在主实例上应用参数更改并重启。

  • 减小参数值:

    • 您应该首先减少主实例的参数值,然后执行重启。然后,将参数更改应用于所有关联的只读副本并执行滚动重启。

监控和调整复制过程

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

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

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

    SELECT extract(epoch from now() - pg_last_xact_replay_timestamp()) AS "ReplicaLag";

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

    副本滞后也可能是间歇性连接问题导致的。您可以通过查看 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 数据已删除。插槽不再可用。

wal_statusunreservedlost 状态只有在 max_slot_wal_keep_size 为非负数时才会显示。

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

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

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

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

RDS for PostgreSQL 只读副本故障排除

下面,您可以找到一些常见 RDS for PostgreSQL 只读副本问题的故障排除思路。

终止导致只读副本滞后的查询

在数据库中长时间运行的处于活动或空闲事务状态的事务可能会干扰 WAL 复制过程,从而增加复制滞后。因此,请务必使用 PostgreSQL pg_stat_activity 视图监控这些事务的运行时。

在主实例上运行类似于以下内容的查询,来查找长时间运行的查询的进程 ID(PID):

SELECT datname, pid,usename, client_addr, backend_start, xact_start, current_timestamp - xact_start AS xact_runtime, state, backend_xmin FROM pg_stat_activity WHERE state='active';
SELECT now() - state_change as idle_in_transaction_duration, now() - xact_start as xact_duration,* FROM pg_stat_activity WHERE state = 'idle in transaction' AND xact_start is not null ORDER BY 1 DESC;

确定查询的 PID 后,您可以选择结束此查询。

在主实例上运行类似于以下内容的查询,来终止长时间运行的查询:

SELECT pg_terminate_backend(PID);