流式复制如何适用于不同的 RDS for PostgreSQL 版本 - Amazon Relational Database Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

流式复制如何适用于不同的 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、14 和 15,默认值为 20。

  • 对于版本 16 及更高版本,默认值为 35。

此参数应设置为略高于实际只读副本数量。如果此参数设置为对只读副本数来说太少,则复制将停止。

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

注意

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 会重新建立流式复制。

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

在以下示例中,您可以找到演示只读副本恢复过程的日志详细信息。该示例来自与源数据库在同一 Amazon Web Services 区域中运行 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 重启,我们建议将参数更改作为滚动重启应用于每个副本。在设置参数时,必须应用以下规则:

  • 增加参数值:

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

  • 减小参数值:

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