在 psycopg2 中处理 Postgresql Error -canceling statement due to conflict with recovery-

Deal with Postgresql Error -canceling statement due to conflict with recovery- in psycopg2

我正在创建一个报告引擎,它在备用服务器上进行几个长查询并使用 pandas 处理结果。一切正常,但有时我在使用 psycopg2 游标执行这些查询时遇到一些问题:查询被取消并显示以下消息:

ERROR: cancelling statement due to conflict with recovery
Detail: User query might have needed to see row versions that must be removed

我正在调查这个问题

PostgreSQL ERROR: canceling statement due to conflict with recovery

https://www.postgresql.org/docs/9.0/static/hot-standby.html#HOT-STANDBY-CONFLICT

但所有解决方案都建议通过修改服务器配置来解决问题。我无法进行这些修改(我们赢得了上一场与 IT 人员的足球比赛:))所以我想知道如何从开发人员的角度处理这种情况。我可以使用 python 代码解决这个问题吗?我的临时解决方案很简单:捕获异常并重试所有失败的查询。也许可以做得更好(我希望如此)。

提前致谢

如果不更改 PostgreSQL 配置(从 PostgreSQL 9.1 开始,您可以将 hot_standby_feedback 设置为 on)。

您正在以正确的方式处理错误——只需重试失败的交易即可。

在运行长查询运行时修改了热备从服务器上的table数据。确保 table 数据未被修改的解决方案(PostgreSQL 9.1+)是暂停从属服务器上的复制并在查询后恢复。

select pg_xlog_replay_pause(); -- suspend
select * from foo; -- your query
select pg_xlog_replay_resume(); --resume

我最近遇到了类似的错误,也不是 dba/devops 可以访问基础数据库设置的人。

我的解决方案是尽可能减少查询时间。显然,这需要对您的表和数据有深入的了解,但我能够通过结合使用更高效的 WHERE 过滤器、GROUPBY 聚合和更广泛地使用索引来解决我的问题。

通过减少服务器端执行时间和数据量,您可以减少发生回滚错误的可能性。

但是,在您缩短的 window 期间仍然可能发生回滚,因此当回滚错误发生时,一个全面的解决方案也会使用一些重试逻辑。

更新:一位同事实现了上述重试逻辑以及批处理查询以减小数据量。这三种解决方案使问题完全消失了。