在待机模式下在 PostgreSQL 数据库上运行查询时出现以下错误。导致错误的查询可以正常工作 1 个月,但是当您查询超过 1 个月时,会出现错误。
ERROR: canceling statement due to conflict with recovery
Detail: User query might have needed to see row versions that must be removed
有关如何解决的任何建议?谢谢
在待机模式下在 PostgreSQL 数据库上运行查询时出现以下错误。导致错误的查询可以正常工作 1 个月,但是当您查询超过 1 个月时,会出现错误。
ERROR: canceling statement due to conflict with recovery
Detail: User query might have needed to see row versions that must be removed
有关如何解决的任何建议?谢谢
无需触摸hot_standby_feedback
。正如其他人所提到的,将其设置为on
可以膨胀大师。想象一下在奴隶上打开交易而不是关闭它。
相反,将max_standby_archive_delay
和设置max_standby_streaming_delay
为一些理智的值:
# /etc/postgresql/10/main/postgresql.conf on a slave
max_standby_archive_delay = 900s
max_standby_streaming_delay = 900s
这样,对持续时间小于 900 秒的从站的查询将不会被取消。如果您的工作负载需要更长的查询,只需将这些选项设置为更高的值。
在热备服务器上运行查询有点棘手——它可能会失败,因为在查询期间,一些需要的行可能会在主服务器上更新或删除。由于主节点不知道查询是在辅助节点上启动的,因此它认为它可以清理(清理)其行的旧版本。然后辅助必须重播此清理,并且必须强制取消所有可以使用这些行的查询。
更长的查询将更频繁地被取消。
您可以通过在主节点上启动可重复的读取事务来解决此问题,该事务执行虚拟查询,然后在辅助节点上运行真正的查询时处于空闲状态。它的存在将防止清理主节点上的旧行版本。
有关此主题和其他解决方法的更多信息,请参阅文档中的Hot Standby — 处理查询冲突部分。
无需在主服务器上启动空闲事务。在 postgresql-9.1 中,解决这个问题最直接的方法是通过设置
hot_standby_feedback = on
这将使 master 知道长时间运行的查询。从文档:
第一个选项是设置参数 hot_standby_feedback,它可以防止 VACUUM 删除最近失效的行,因此不会发生清理冲突。
为什么这不是默认值?这个参数是在初始实现之后添加的,它是备用服务器影响主服务器的唯一方式。
如此处所述:hot_standby_feedback = on
嗯,它的缺点是standby会使master膨胀,这可能也让一些人感到惊讶
在这里:
max_standby_streaming_delay 的设置是什么?我宁愿将其默认为 -1 而不是默认的 hot_standby_feedback 。这样你在备用服务器上所做的只会影响备用服务器
所以我加了
max_standby_streaming_delay = -1
对我们来说不再有pg_dump
错误,也不会出现膨胀 :)
对于 AWS RDS 实例,请查看http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html
热备从服务器上的表数据在长时间运行的查询运行时被修改。确保表数据未被修改的解决方案(PostgreSQL 9.1+)是暂停复制并在查询后恢复:
select pg_xlog_replay_pause(); -- suspend
select * from foo; -- your query
select pg_xlog_replay_resume(); --resume
我将在上面添加一些更新的信息和对@max-malysh 出色答案的引用。
简而言之,如果你在master上做某事,它需要在slave上复制。Postgres 为此使用 WAL 记录,这些记录在主服务器上的每个记录操作之后发送到从服务器。从机然后执行动作,两者再次同步。在几种情况之一中,您可能会在从站上与 WAL 操作中从主站传入的内容发生冲突。在大多数情况下,slave 上发生的事务与 WAL 操作想要更改的内容相冲突。在这种情况下,您有两种选择:
我们关心 #1 和两个值:
max_standby_archive_delay
- 这是在主从之间长时间断开连接后使用的延迟,当从 WAL 存档中读取数据时,这不是当前数据。max_standby_streaming_delay
- 当通过流复制接收到 WAL 条目时,用于取消查询的延迟。通常,如果您的服务器用于高可用性复制,您希望这些数字保持简短。(如果没有给出单位,则为毫秒)的默认设置30000
就足够了。但是,如果您想设置可能具有非常长时间运行的查询的存档、报告或只读副本,那么您需要将其设置为更高的值以避免取消查询。上面推荐的900s
设置似乎是一个很好的起点。我不同意官方文档将无限值设置-1
为一个好主意——这可能会掩盖一些错误的代码并导致很多问题。
关于长时间运行的查询并将这些值设置得更高的一个警告是,在从属服务器上与导致 WAL 操作延迟的长时间运行的查询并行运行的其他查询将看到旧数据,直到长查询完成。开发人员需要了解这一点并序列化不应同时运行的查询。
有关如何max_standby_archive_delay
和max_standby_streaming_delay
工作以及为什么的完整说明,请转到此处。
答案可能为时已晚,但我们在生产中面临同样的问题。之前我们只有一个 RDS,随着应用端用户数量的增加,我们决定为其添加只读副本。只读副本在暂存阶段可以正常工作,但是一旦我们转移到生产环境,我们就会开始遇到同样的错误。
所以我们通过在 Postgres 属性中启用hot_standby_feedback属性来解决这个问题。我们参考了以下链接
https://aws.amazon.com/blogs/database/best-practices-for-amazon-rds-postgresql-replication/
我希望它会有所帮助。
同样,这是@Artif3x 阐述@max-malysh 出色答案的第二个警告,两者都在上面。
随着来自主服务器的任何延迟应用事务,追随者将拥有一个较旧的、陈旧的数据视图。因此,虽然通过设置 max_standby_archive_delay 和 max_standby_streaming_delay 为追随者的查询提供时间来完成是有意义的,但请记住这两个警告:
如果用于备份的追随者的价值最终与托管查询有太多冲突,则一种解决方案将是多个追随者,每个追随者都针对一个或另一个进行了优化。
另外,请注意,一行中的多个查询可能会导致 wal 条目的应用不断延迟。因此,在选择新值时,不仅仅是单个查询的时间,而是一个移动窗口,每当有冲突的查询开始时就会启动,并在最终应用 wal 条目时结束。