PostgreSQL连接在执行大型ins时意外关闭

2024-10-04 05:27:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我用之前从另一个数据库中选择的~11.000.000行填充PostgreSQL表。我使用Python和psycopg2。整个过程估计需要1.5小时才能完成。但是,在大约30分钟后,我收到“连接意外关闭”异常。源代码如下:

incursor = indb.cursor()
incursor.execute("SELECT ...")
indb.commit() # (1) close transaction
outcursor = outdb.cursor()
rows = 0
for (col1, col2, col3) in incursor: # incursor contains ~11.000.000 rows
    outcursor.execute("INSERT ...", (col1, col2, col3)) # This fails after ~30 minutes
    row += 1
    if row % 100 == 0: # (2) Write data every 100 rows
         outcursor.close()
         outdb.commit()
         outcursor = outdb.cursor()
incursor.close()
outcursor.close()
outdb.commit()

在第一次失败的尝试之后,我插入了(1)和{},假设一个打开的事务的时间上限为~30分钟,或者一个游标有一个挂起的插入的上限。似乎这些假设都不是真的,错误就在别的地方。在

这两个数据库都存储在一个VirtualBox机器上,我通过主机的端口转发来连接它。我在主机上运行程序。在

这两个数据库只是为了测试目的,它们没有其他连接要管理。也许我必须重写这个问题来解决这个问题,但是我需要非常耗时的其他地方的插入(运行大约几天),所以我非常关心psycopg2或PostgreSQL中隐藏的时间限制。在


Tags: 数据库closeexecutepostgresqlcursorpsycopg2col2col3
3条回答

我有一个django管理命令,可以更新成千上万的行。过了一段时间,我看到了同样的错误。我相信内存使用量超出了限制。但不知道如何在事务中手动控制命令。在

我不知道postgresql本身有任何这样的“隐藏”超时。PostgreSQL确实有statement_timeout,但是如果你点击了,你应该在服务器日志中得到一个ERROR: canceling statement due to statement timeout(它也会记录被取消的语句)。我不能代表psycopg2说话。一定要检查服务器日志中的任何相关信息。在

可能是网络问题?长时间运行的语句将是一个长时间处于空闲状态的TCP连接。也许你的端口转发会清除空闲超过30分钟的连接?也许你的TCP连接没有使用keepalive。Postgresql有一些用于调整TCP keepalive的设置(TCP_keepalives_interval等),您可能还需要进行一些内核/网络配置,以确保它们实际上已启用。在

例如,我刚试着在这里连接到我自己的机器,tcp_keepalives_interval默认值为7200,即2小时。如果你的端口转发在30分钟后被切断,这个默认值就不行了。您可以覆盖客户机连接字符串中使用的设置(假设您可以直接旋转conninfo字符串),或者在用户/数据库属性中设置GUC变量,或者postgresql.conf一

参见:

为了插入数以百万计的行,我将查看官方的guide来填充数据库,并考虑使用copy。在

相关问题 更多 >