从 RDS postgres 只读副本流式传输大型结果集并且 sqlalchemy 提前终止

Ste*_*ore 7 postgresql amazon-web-services amazon-rds read-replication

我正在尝试使用 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....
Run Code Online (Sandbox Code Playgroud)

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

TransactionRollbackError: terminating connection due to conflict with recovery
DETAIL:  User query might have needed to see row versions that must be removed.
Run Code Online (Sandbox Code Playgroud)

我在 google 上搜索到的所有内容都表明要在 RDS 中的只读副本上设置以下参数:

hot_standby_feedback=1
max_standby_archive_delay=600000
max_standby_streaming_delay=600000
Run Code Online (Sandbox Code Playgroud)

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

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

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

我完全被难住了,非常感谢任何帮助。

Ste*_*ore 5

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

wal_receiver_timeout=600000
Run Code Online (Sandbox Code Playgroud)

设置就成功了!