2

我们正在运行一个运行此存储过程的 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 回答 2

3

从手册:

当一个表被集群时,会在它上面获取一个 ACCESS EXCLUSIVE 锁。这可以防止任何其他数据库操作(读取和写入)在 CLUSTER 完成之前对表进行操作。

你确定你必须每小时进行一次集群吗?使用更好的填充因子和 autovacuum,您的表格不会增长太多,并且表格中不会有死元组。

于 2011-01-13T18:40:52.587 回答
1

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

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

于 2011-01-14T23:00:58.903 回答