3

我正在尝试使用 SQLAlchemy 在设置为只读副本的 Postgres 9.4 RDS 服务器上使用以下代码运行大型查询。

    # self.sa_engine is a SQLAlchemy engine
    with self.sa_engine.connect() as conn:
        conn = conn.execution_options(stream_results=True)

        # pd = pandas
        # self.sql = "select * from mylargetable"
        for chunk in  pd.read_sql(self.sql, conn, chunksize=50000):
            # do stuff, write file, etc....

问题是我在大约 30-60 秒后收到以下错误。在此期间,文件正在按预期写入。

TransactionRollbackError: terminating connection due to conflict with recovery
DETAIL:  User query might have needed to see row versions that must be removed.

我用谷歌搜索的所有内容都说要在 RDS 中的只读副本上设置以下参数:

hot_standby_feedback=1
max_standby_archive_delay=600000
max_standby_streaming_delay=600000

设置这些参数后,我希望仅当查询运行时间超过 10 分钟时才会出现上述错误,但我会在 30-60 秒后得到它。

此外,我对这个问题的理解是,只有在对副本的查询运行时修改主数据库中的表时才会发生这种情况。但是,此表已数月未更新。

当我针对主数据库运行它(我无法在生产中执行此操作)以及针对只读副本上的较小表运行它时,所有这些都有效。

我完全被难住了,如果有任何帮助,我将不胜感激。

4

2 回答 2

3

问完这个问题后,我搜索了默认设置为 30 秒的参数并找到了解决方案。我还必须调整一个参数:

wal_receiver_timeout=600000

设置成功了!

于 2018-11-27T02:54:55.800 回答
1

如果由于任何原因您无权更改数据库的配置,和/或如果这样做没有帮助。完全客户端修复可能是:

使用isolation_level="REPEATABLE_READ"

my_engine = sqlalchemy.create_engine(f"{my_db_url}", isolation_level="REPEATABLE_READ")

这在线程中同样建议:https ://www.postgresql.org/message-id/7F74C5EA-6741-44FC-B6C6-E96F18D761FB@simply.name

这个“修复”当然应该与隔离级别的知识一起使用:https ://www.postgresql.org/docs/14/transaction-iso.html 。

于 2021-10-27T12:33:21.820 回答