我为 Amazon Relational Database Service (Amazon RDS) for PostgreSQL 实例设置了只读副本。当我查询只读副本时,我收到了“canceling statement due to conflict with recovery”(由于与恢复冲突而取消语句)错误。
解决方法
如果主实例和只读副本之间存在复制冲突,则您会收到 cancelling statement(取消语句)错误。PostgreSQL 无法将 WAL 信息应用于只读副本,因为更改可能会阻止只读副本上正在发生的活动。例如,当在只读副本中删除的表上运行 SELECT 语句时,您在主实例上运行了 DROP 语句。如果只读副本应用 WAL 记录并取消 SELECT 语句,则您会收到 cancelling statement(取消语句)错误。
要解决 canceling statement(取消语句)错误,请根据错误消息的详细信息在只读副本上设置自定义参数。
您还可以使用只读副本上的 pg_stat_database_conflicts 视图,以了解有关由于与恢复冲突而取消的语句的统计信息。有关详细信息,请参阅 PostgreSQL 网站上的 27.2.18 pg_stat_database_conflicts。
错误消息详细信息: “用户持有关系锁的时间过长”
要解决此问题,请更改 max_standby_streaming_delay 或 max_standby_archive_delay 参数,以便在只读副本取消冲突的备用语句之前留出更多时间。如果只读副本从流复制中读取 WAL 数据,则修改 max_standby_streaming_delay 参数。如果只读副本从 Amazon Simple Storage Service (Amazon S3) 中的存档位置读取 WAL 数据,则修改 max_standby_archive_delay 参数。
有关这些参数的详细信息,请参阅 PostgreSQL 网站上的 max_standby_streaming_delay (integer) 和 max_standby_archive_delay (integer)。
如果将参数值设置为 0,则只读副本会取消冲突的查询并将 WAL 条目应用于副本实例。如果将该值设置为 -1,则会允许副本实例一直等待冲突的查询完成,且复制滞后会增加。根据您的使用案例,调整这些参数的值以平衡查询取消或复制滞后。
**注意:**如果增加 max_standby_archive_delay 以保留与读取 WAL 存档条目冲突的查询,则最佳做法是同时增加 max_standby_streaming_delay 以防止取消。
错误消息详细信息: “查看必须删除的行版本可能需要执行用户查询”
当只读副本上的事务正在读取在主实例上设置为删除的元组时,通常会发生此问题。要解决此问题,可能需要激活 hot_standby_feedback 参数。
当激活 hot_standby_feedback 时,只读副本会向主实例发送反馈消息,其中包含有关最早的活动事务的信息。因此,主实例不会删除事务可能需要的记录。有关此参数的详细信息,请参阅 PostgreSQL 网站上的 hot_standby_feedback (boolean)。
**重要事项:**默认情况下,hot_standby_feedback 参数处于禁用状态。当您在只读副本上激活 hot_standby_feedback 时,在只读副本上长时间运行查询可能会导致主实例上出现表膨胀。清理操作不会删除长时间运行的查询可能需要的死元组(膨胀)。为了降低膨胀风险,最佳做法是同时减少 autovacuum_threshold 和 autovacuum_vacuum_scale_factor 并增加 autovacuum_cost_limit。