使用Psycopg2运行其他事务时,CLUSTER不会缩小表大小

时间:2011-01-13 16:44:42

标签: django postgresql psycopg2

我们正在运行一个运行此存储过程的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产生影响?

很少有观察 -

  1. 导入过程运行时运行CLUSTER命令 - 大小不会下降
  2. 当我停止导入过程然后运行CLUSTER时 - 大小会下降
  3. 当我停止导入过程并重新开始导入过程时,然后运行CLUSTER命令 - 大小确实下降
  4. 对这个问题的任何想法?

2 个答案:

答案 0 :(得分:3)

从手册:

  

当一个表被聚类时,一个   获取ACCESS EXCLUSIVE锁定   它。这可以防止任何其他数据库   操作(读写)   从经营桌上直到   CLUSTER完成了。

你确定每小时必须使用CLUSTER吗?使用更好的fillfactor和autovacuum,你的表不会增长那么多,你不会在表中有死元组。

答案 1 :(得分:1)

好的 - 我找到了罪魁祸首。

问题是某种程度上集群或真空没有删除死元组,因为当我们在django环境中直接使用pstcopg2时发生了一些奇怪的交互。隔离psycopg代码并从import-process中删除django相关代码后,一切正常。这解决了问题,现在我可以在不停止导入过程的情况下对其进行抽真空或群集。