我们正在运行一个运行此存储过程的python进程,该进程将文件从某个目录导入到postgres数据库。首先将这些文件导入内存表,然后导入磁盘表。内存表的实际大小永远不会超过30 MB。随着这个表不断更新,表的大小增加(因为死元组)。为了控制事情,我们需要对表执行CLUSTER操作。我使用psycopg2模块运行存储过程和表CLUSTER,但如果导入进程正在运行,表的大小永远不会下降。但是如果我停止导入过程并运行CLUSTER,则表的大小会下降。由于性能原因,我应该能够在不停止导入过程的情况下运行CLUSTER命令。
我尝试了手动提交,ISOLATION_LEVEL_AUTOCOMMIT但这些都没有奏效。 以下是流程的示例代码 -
while True:
-get the filenames in directory
for filpath in filenames:
conn = psycopg2.connect("dbname='dbname' user='user' password='password'")
cursor = conn.cursor()
# Calls a postgresql function that reads a file and imports it into
# a table via INSERT statements and DELETEs any records that have the
# same unique key as any of the records in the file.
cursor.execute("SELECT import('%s', '%s');" % (filepath, str(db_timestamp))
conn.commit()
cursor.close()
conn.close()
os.remove(get_media_path(fname))
使用类似的conn对象,我想每小时运行一次CLUSTER命令 -
conn = psycopg2.connect("dbname='dbname' user='user' password='password'")
cursor = conn.cursor()
cursor.execute("CLUSTER table_name")
conn.commit()
cursor.close()
conn.close()
另外,我尝试设置 -
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
另一条信息 - 我在django环境中运行了所有这些。我无法使用django连接对象来执行任务,因为 - django无法释放与我的线程代码的连接,很快数据库就停止接受连接。这种混合环境是否会对psycopg产生影响?
很少有观察 -
对这个问题的任何想法?
答案 0 :(得分:3)
从手册:
当一个表被聚类时,一个 获取ACCESS EXCLUSIVE锁定 它。这可以防止任何其他数据库 操作(读写) 从经营桌上直到 CLUSTER完成了。
你确定每小时必须使用CLUSTER吗?使用更好的fillfactor和autovacuum,你的表不会增长那么多,你不会在表中有死元组。
答案 1 :(得分:1)
好的 - 我找到了罪魁祸首。
问题是某种程度上集群或真空没有删除死元组,因为当我们在django环境中直接使用pstcopg2时发生了一些奇怪的交互。隔离psycopg代码并从import-process中删除django相关代码后,一切正常。这解决了问题,现在我可以在不停止导入过程的情况下对其进行抽真空或群集。