【问题标题】:Deal with Postgresql Error -canceling statement due to conflict with recovery- in psycopg2在 psycopg2 中处理 Postgresql 错误 - 由于与恢复冲突而取消语句
【发布时间】:2016-11-25 15:23:19
【问题描述】:

我正在创建一个报告引擎,它在备用服务器上进行几个长查询并使用 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 python-2.7 psycopg2


    【解决方案1】:

    在不更改 PostgreSQL 配置的情况下,您无法避免该错误(从 PostgreSQL 9.1 开始,您可以将 hot_standby_feedback 设置为 on)。

    您正在以正确的方式处理错误 - 只需重试失败的事务。

    【讨论】:

    • 我遇到了同样的问题,据我所知,这个配置不能从 python/psycopg2 更改,对吗?简单地重试事务对我不起作用...
    • 您可以将hot_standby_feedback 更改为ALTER SYSTEM,然后再更改为pg_reload_conf()。也许您的问题仍然存在,因为主服务器上的活动太多,而且您的查询太长,以至于您一次又一次地遇到问题。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我最近遇到了类似的错误,而且我也不是能够访问底层数据库设置的 dba/devops 人。

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2013-01-13
        • 1970-01-01
        • 2012-10-18
        • 1970-01-01
        • 2014-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多