【发布时间】:2011-02-23 10:45:38
【问题描述】:
我正在使用之前从另一个数据库中选择的 ~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) 和(2),假设打开的事务的时间上限约为 30 分钟,或者游标具有挂起插入的上限。似乎这些假设都不成立,错误出在其他地方。
两个数据库都存储在我通过主机端口转发连接的 VirtualBox 机器上。我在主机上运行程序。
这两个数据库仅用于测试目的,它们没有其他要管理的连接。也许我必须重写这个问题来解决这个问题,但我需要在其他地方进行非常耗时的插入(运行大约几天),所以我非常担心psycopg2 或 PostgreSQL 中的一些隐藏时间限制。
【问题讨论】:
-
我认为问题可能出在配置中的 work_mem 变量中。 AFAIK 此变量设置一个连接允许的最大内存。检查日志应该有一个关于什么是错误的条目
-
但是 SELECT 语句根本不起作用,不是吗?但我失去了与
outdb的联系。 -
使用
COPY或更大的事务。在单个事务中仅执行 100 条记录,为您提供大约 110.000 个事务来完成整个工作。单个 7400rpm 驱动器每秒只能处理 120 次提交(除非它因为缓存而存在,否则会使其不可靠)。您当前的问题听起来像是网络问题。 -
你在使用连接池吗?一些池有一个默认配置,如果在一定时间后没有返回,则会关闭连接,以避免连接泄漏。
-
work_mem 没有设置一个连接的最大内存——默认只有 1MB。
标签: python postgresql psycopg