Повторяющиеся обновления Postgres массивов, ведущих к раздутию? - PullRequest
1 голос
/ 11 марта 2019

Я запускаю скрипт Python, который обрабатывает данные временных рядов для ряда различных метрик, а затем записывает результаты в базу данных Postgres.

Временные ряды предполагают 40 эпох, сохраненных как real[40] столбец массива в базе данных.

При записи выходных данных для всех 40 эпох в таблицу за один снимок (пакетное обновление по всем строкам) все казалось работающим нормально.т.е.

UPDATE my_table SET
  arr_col_1 = {1, 2, 3, ... 40},
  arr_col_2 = {1, 2, 3, ...40},
  ...
  arr_col_90 = {1, 2, 3, ...40};

Однако итеративная запись результатов соответствующих эпох в каждую позицию в массиве, похоже, занимает все свободное место на жестком диске, например

UPDATE my_table SET
  arr_col_1[1] = 1,
  arr_col_2[1] = 1,
  ...
  arr_col_90[1] = 1;

UPDATE my_table SET
  arr_col_1[2] = 2,
  arr_col_2[2] = 2,
  ...
  arr_col_90[2] = 2;

-- repeat x 38 more times

ПричинаИтеративная стратегия заключается в размещении большего количества строк, для которых результаты за 40 эпох не помещаются в память одновременно.

Насколько мне известно, UPDATE запросы будут удалять и перезаписывать данные строкв определенных ситуациях, но мне неясно, когда это произойдет и как это может быть связано с массивами.Есть ли способ итеративно обновлять массивы в большом количестве строк, не приводя к переполнению базы данных?

Ответы [ 2 ]

3 голосов
/ 11 марта 2019

Как правильно отметили другие, этот подход не очень подходит для режима работы PostgreSQL.

Однако вы можете использовать оптимизацию под названием HOT:

  • Объявите вашу таблицу с fillfactor меньше 100, чтобы INSERT s оставляли свободное место в каждом блоке:

    ALTER TABLE my_table SET (fillfactor = 50);
    

    Этот параметр влияет только на будущие действия, вам придется реорганизовать таблицудля того, чтобы повлиять на существующие данные.Если вы обновляете каждую строку в таблице, вам может потребоваться настройка до 30, чтобы она была эффективной.

  • Убедитесь, что обновляемые столбцы не не иметь индекс для них.

Тогда PostgreSQL может использовать & ldquo; HOT update ”и восстанавливать записи мертвой таблицы на лету, что устраняет необходимость в автоочистке, которая, очевидно, не может идти в ногуна вашей таблице.

Проверьте столбец n_tup_hot_upd в строке pg_stat_user_tables таблицы, чтобы увидеть, работает ли она.

1 голос
/ 11 марта 2019

Postgres использует MVCC, который выполняет копирование при записи.

UPDATE копирует всю строку в новую, а старая помечается для удаления, но само удаление происходит только во время вакуума, который периодически выполняется демоном автовакуума.

Вы можете освободить место самостоятельно, запустив

VACUUM

Сколько места на диске у вас осталось? Я никогда не слышал о такой проблеме с негигантской базой данных.

...