CLUSTER не уменьшает размер таблицы при выполнении других транзакций с использованием Psycopg2

Мы запускаем процесс python, который запускает эту хранимую процедуру, которая импортирует файлы из определенного каталога в базу данных postgres. Эти файлы сначала импортируются в таблицу в памяти, а затем в таблицу на диске. Фактический размер таблицы в памяти никогда не должен превышать 30 МБ. Поскольку эта таблица постоянно обновляется, размер таблицы растет (из-за мертвых кортежей). Чтобы держать все под контролем, нам нужно выполнить операцию 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 - размер уменьшается

Есть мысли по проблеме?


person Sujit    schedule 13.01.2011    source источник


Ответы (2)


Из руководства:

Когда таблица кластеризуется, на нее устанавливается блокировка ACCESS EXCLUSIVE. Это предотвращает выполнение любых других операций базы данных (как чтения, так и записи) в таблице до тех пор, пока CLUSTER не будет завершен.

Вы уверены, что вам нужно КЛАСТЕРИТЬ каждый час? С лучшим коэффициентом заполнения и автоочисткой ваша таблица не будет так сильно расти, и в ней не будет мертвых кортежей.

person Frank Heikens    schedule 13.01.2011
comment
да, я в порядке, предотвращая чтение и запись во время работы кластера. Но проблема в том, что размер не уменьшается после запуска кластера. Также не помогает автовакуум и полный вакуум. размер таблицы продолжает расти. - person Sujit; 13.01.2011
comment
Когда даже VACUUM FULL не сжимает таблицу, у вас вообще не так много мертвых кортежей. Но опять же, используйте лучший коэффициент заполнения, чтобы дать базе данных возможность использовать ГОРЯЧИЕ обновления. Это поможет избежать необходимости в дополнительном пространстве. - person Frank Heikens; 13.01.2011
comment
Я ценю, что вы отвечаете на эту тему. Но вы понимаете, в чем здесь проблема. Дело не в том, что вакуум заполнен или кластер не уменьшает размер таблицы. Они уменьшают размер таблицы, когда я останавливаю процесс импорта и запускаю любой из них. Но когда я запускаю процесс импорта, который постоянно вставляет и удаляет (используя хранимую процедуру, запускаемую psycopg2) из ​​таблицы, то, даже если я запускаю CLUSTER или VACCUM FULL, размер не уменьшается. - person Sujit; 13.01.2011
comment
И это потому, что CLUSTER и VACUUM FULL нуждаются в блокировке таблицы, которую они не могут получить из-за других процессов. Вам действительно нужна КЛАСТЕРАЦИЯ? Как я уже говорил, использование лучшего коэффициента заполнения может изменить все, и вам не понадобится CLUSTER вообще или так часто. - person Frank Heikens; 13.01.2011

ОК - я нашел виновника.

Проблема заключалась в том, что кластер или вакуум не удаляли мертвые кортежи, потому что происходило какое-то странное взаимодействие, когда мы использовали pstcopg2 непосредственно в среде django. После изоляции кода psycopg и удаления кода, связанного с django, из процесса импорта все заработало нормально. Это решило проблему, и теперь я могу очистить или сгруппировать его, не останавливая процесс импорта.

person Sujit    schedule 14.01.2011