为什么我的 RDS for PostgreSQL 数据库实例中出现复制滞后和错误?

2 分钟阅读
0

我在 Amazon Relational Database Service (Amazon RDS) for PostgreSQL 实例中遇到了复制错误和滞后。

简短描述

您可以通过向实例添加只读副本来扩展 Amazon RDS for PostgreSQL 数据库实例的读取量。RDS for PostgreSQL 使用 PostgreSQL 原生流式传输复制来创建源数据库实例的只读副本。此只读副本数据库实例是源数据库实例的异步创建物理副本。这意味着该副本有时无法与主数据库实例保持同步。因此,可能会出现复制滞后。副本数据库由特殊连接创建,该连接将预写日志 (WAL) 数据从源数据库实例传输到只读副本。因此,只读副本会检查 WAL 日志以复制在主实例上执行的更改。当只读副本在主实例上找不到 WAL 时,将从 Amazon Simple Storage Service (Amazon S3) 中存档的 WAL 数据恢复只读副本。有关更多信息,请参阅流式传输复制如何适用于不同的 RDS for PostgreSQL 版本

您可以通过查看 Amazon RDS ReplicaLag 指标来监控 Amazon CloudWatch 中的副本滞后。此指标显示只读副本落后于其源数据库实例的程度。Amazon RDS 监控只读副本的复制状态。然后,如果复制因任何原因停止,它会将 Amazon RDS 控制台中的复制状态字段更新为错误。ReplicaLag 指标指示只读副本与源数据库实例保持同步的程度,以及源数据库实例与特定读取实例之间的滞后量。

解决方案

当副本滞后增加时,您可能会在 RDS for PostgreSQL 错误日志中看到以下错误之一:

  • 流式传输复制已停止:当主实例和副本实例之间的流式传输复制中断时,您会收到此错误。在此情况下,复制将从 Amazon S3 中的存档位置开始重放,从而进一步增加副本滞后。
  • 流式传输复制已终止:如果复制连续停止 30 天以上(手动或由于复制错误),则会出现此错误。在此情况下,Amazon RDS 会终止主数据库实例和所有只读副本之间的复制,以防止主实例的存储需求增加和失效转移时间延长。

即使复制终止,只读副本实例仍可用。但是,无法恢复复制,因为在复制终止后,只读副本所需的事务日志会从主实例中删除。

副本滞后量增加的最常见原因如下:

  • 主实例和副本实例之间的配置差异
  • 主实例的写入工作负载繁重
  • 长时间运行的事务
  • 主实例表的独占锁
  • WAL 文件损坏或丢失
  • 网络问题
  • 参数设置不正确
  • 无事务

主实例和只读副本之间的配置差异

不正确的副本实例配置可能会影响复制性能。只读副本处理与源实例类似的写入工作负载以及其他读取查询。因此,请使用与源实例相同或更高级别实例类和存储类型的副本。由于副本必须重放与源实例相同的写入活动,因此使用级别较低实例类的副本可能会导致副本延迟过长并增加复制滞后。不匹配的存储配置也会增加复制滞后。

主实例的写入工作负载繁重

主实例上的大量写入工作负载可能会导致大量的 WAL 文件涌入。WAL 文件数量的增加以及在只读副本上重放这些文件可能会降低总体复制性能。因此,当您看到副本滞后增加时,请务必检查主实例上的写入活动。您可以使用 CloudWatch 指标或增强监控来分析此工作负载。查看 TransactionLogsDiskUsageTransactionLogsGenerationWriteIOPSWriteThroughputWriteLatency 的值,以了解源实例是否承担繁重的写入工作负载。您还可以在吞吐量级别检查性能瓶颈。每种实例类型都有其专用的吞吐量。有关更多信息,请参阅数据库实例类的硬件规格

要避免此问题,请控制和分发源实例的写入活动。与其同时执行许多写入活动,不如将任务分解为较小的任务服务包,然后在多个事务中均匀分发这些服务包。您可以使用针对指标的 CloudWatch 提醒(例如 WritelatencyWriteIOPS),以便在源实例上出现大量写入时收到通知。

长时间运行的事务

在数据库中长时间运行的活动事务可能会干扰 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';

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

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

SELECT pg_terminate_backend(PID);

您还可以选择重写或调整查询,以避免长时间运行的事务。

主实例表的独占锁

在主实例上运行 DROP TABLE、TRUNCATE、REINDEX、VACUUM FULL、REFRESH MATERIALIZED VIEW(无 CONCURRENTLY)等命令时,PostgreSQL 会处理访问独占锁。此锁可防止所有其他事务在锁的保留持续时间内访问此表。通常,表将保持锁定状态,直到事务结束。此锁定活动记录在 WAL 中,然后由只读副本重放和保持。表处于“独占访问”锁定的时间越长,复制滞后的时间就越长。

为避免此问题,最佳实践是通过定期查询 pg_lockspg_stat_activity 目录表来监控事务。

示例:

SELECT pid, usename, pg_blocking_pids(pid) AS blocked_by, QUERY AS blocked_query<br>FROM pg_stat_activity<br>WHERE cardinality(pg_blocking_pids(pid)) > 0;

WAL 文件损坏或丢失

WAL 文件损坏或丢失可能会导致副本滞后。在此情况下,您会在 PostgreSQL 日志中看到一条错误,指出无法打开 WAL。您可能还会看到错误“请求的 WAL 分段 XXX 已被移除”。

网络问题

主实例和副本实例之间的网络中断可能会导致流式传输复制出现问题,从而可能导致副本滞后增加。

参数设置不正确

错误地设置服务器配置参数组中的某些自定义参数可能会导致副本滞后增加。以下是必须正确设置的一些参数:

  • **wal_keep_segments:**此参数指定主实例在 pg_wal 目录中保存的 WAL 文件的数量。此参数的默认值设置为 32。如果此参数设置的值不足以满足您的部署需求,则只读副本可能会落后,从而导致流式传输复制停止。在此情况下,RDS 会生成复制错误,并通过从 S3 重放主实例的存档 WAL 数据开始恢复只读副本。此恢复过程将持续到只读副本可以继续流式传输复制为止。
    **注意:**在 PostgreSQL 版本 13 中,wal_keep_segments 参数名为 wal_keep_size。此参数的用途与 wal_keep_segments 相同。但是,此参数的默认值以 MB 为单位定义 (2048 MB),而不是以文件数定义。
  • **max_wal_senders:**此参数指定主实例通过流式传输复制协议可以同时支持的最大连接数。对于 PostgreSQL 13 及更高版本的 RDS,此参数的默认值为 20。此参数应设置为略高于实际只读副本数的值。如果将此参数设置为小于只读副本数的值,则复制将停止。
  • **hot_standby_feedback:**此参数指定副本实例是否向主实例发送有关当前在副本实例中运行的查询的反馈。通过启用此参数,您可以在源实例上整理以下错误消息,并推迟对相关表执行 VACUUM 操作,除非副本实例中的读取查询已完成。因此,开启 hot_standby_feedback 的副本实例可以为长时间运行的查询提供服务。但是,此参数可能会使源实例上的表膨胀。请务必监控副本实例中长时间运行的查询,以避免出现存储空间不足和主实例中的事务 ID 环绕等严重问题。
ERROR: canceling statement due to conflict with recovery
Detail: User query might have needed to see row versions that must be removed
  • **max_standby_streaming_delay/max_standby_archive_delay:**您可以在副本实例上启用参数,例如 max_standby_archive_delaymax_standby_streaming_delay,以完成长时间运行的读取查询。如果在副本上运行读取查询时修改了源数据,则这些参数会暂停副本中的 WAL 重放。如果这些参数的值为 -1,WAL 重放将等到读取查询完成。但是,这种暂停会无限期地增加复制滞后,并由于 WAL 累积而导致源位置的存储消耗很高。

无事务

如果源数据库实例上没有发生用户事务,则 PostgreSQL 只读副本会报告最多五分钟的复制滞后。


相关信息

使用 Amazon RDS for PostgreSQL 的只读副本

服务器配置的 PostgreSQL 文档

AWS 官方
AWS 官方已更新 2 年前