在待机模式下在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
有关如何解决的任何建议?谢谢
Answers:
在热备用服务器上运行查询有些棘手-可能会失败,因为在查询过程中某些需要的行可能在主数据库上被更新或删除。作为主数据库,它不知道查询是在辅助数据库上启动的,因此认为它可以清除(清理)其行的旧版本。然后,secondary必须重播此清理操作,并且必须强制取消所有可以使用这些行的查询。
较长的查询将被更频繁地取消。
您可以通过在主数据库上启动可重复的读取事务来解决此问题,该事务将执行虚拟查询,然后在次要数据库上运行实际查询时处于空闲状态。它的存在将防止在主数据库上清除旧行版本。
文档的“ 热备-处理查询冲突”部分介绍了有关此主题的更多信息以及其他解决方法。
无需触摸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秒的从站的查询将不会被取消。如果您的工作量需要更长的查询,只需将这些选项设置为更高的值。
max_standby_archive_delay
可能需要小于另一个。
ms
,即900s = 16分钟= 900000ms。
ms
cloud.google.com/sql/docs/postgres/…中
如前所述这里约hot_standby_feedback = on
:
好吧,它的缺点是备用数据库可能会使主数据库膨胀,这对于某些人来说也可能会感到惊讶
而在这里:
使用max_standby_streaming_delay的什么设置?我宁愿将其默认设置为-1而不是将默认的hot_standby_feedback设置为on。这样,您在备用数据库上执行的操作只会影响备用数据库
所以我加了
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
xlog
被替换为wal
,因此您要调用pg_wal_replay_pause()
和pg_wal_replay_resume()
。
答案可能为时已晚,但我们在生产中面临同样的问题。之前我们只有一个RDS,随着应用程序方面用户数量的增加,我们决定为其添加只读副本。只读副本在登台上可以正常工作,但是一旦移至生产环境,我们就会开始遇到相同的错误。
因此,我们通过在Postgres属性中启用hot_standby_feedback属性来解决此问题。我们引用了以下链接
https://aws.amazon.com/blogs/database/best-practices-for-amazon-rds-postgresql-replication/
希望对您有所帮助。
我将添加一些更新的信息和对@ max-malysh上面出色答案的引用。
简而言之,如果您在主服务器上执行某些操作,则需要将其复制到从服务器上。Postgres为此使用WAL记录,这些记录在主服务器上的每个已记录操作之后发送到从属服务器。然后,从站执行该动作,并且两者再次同步。在几种情况之一中,您可能会在从属服务器上与主服务器在WAL动作中产生的冲突。在大多数情况下,从服务器上正在发生事务,该事务与WAL动作要更改的发生冲突。在这种情况下,您有两种选择:
我们关心的是#1和两个值:
max_standby_archive_delay
-这是从WAL归档文件(不是当前数据)中读取数据后,主机和从机之间长时间断开后使用的延迟。max_standby_streaming_delay
-通过流复制接收到WAL条目时用于取消查询的延迟。通常,如果您的服务器是用于高可用性复制的,则希望保持这些数字简短。默认设置30000
(毫秒,如果没有给出单位)就足够了。但是,如果您想设置诸如存档,报告或只读副本之类的查询,这些查询可能会运行很长时间,那么您需要将其设置为更高的值,以避免查询被取消。900s
上面推荐的设置似乎是一个很好的起点。我不同意将无限值设置-1
为一个好主意的官方文档,因为这可能会掩盖一些错误的代码并引起很多问题。
关于长时间运行的查询并将这些值设置为较高的一个警告是,与在长期运行的查询并行执行的其他查询与导致WAL动作延迟的长时间运行的查询并行运行,直到长时间的查询完成为止。开发人员将需要理解这一点并序列化不应同时运行的查询。
有关如何充分的解释max_standby_archive_delay
和max_standby_streaming_delay
工作,所以,去这里。
同样,以上是@ Artif3x对@ max-malysh出色答案的详细说明。
如果主服务器延迟处理交易,则追随者将获得较旧的旧数据视图。因此,在通过设置max_standby_archive_delay和max_standby_streaming_delay为跟随者提供查询时间的同时,请注意以下两个注意事项:
如果备份跟随者的价值最终与托管查询冲突太多,则一种解决方案将是多个跟随者,每个跟随者都针对一个或另一个进行优化。
另外,请注意,连续几个查询可能会导致wal条目的应用不断延迟。因此,在选择新值时,不仅是单个查询的时间,而且移动窗口会在发生冲突的查询时开始,并在最终应用wal条目时结束。