2017-01-13 3 views
0

Мы запускаем postgresql 9.5.2 в экземпляре RDS. Одна вещь, которую мы заметили, заключалась в том, что некоторая таблица иногда растет очень быстро по размеру.таблица быстрого роста в postgresql

В рассматриваемой таблице имеется только 33 тыс. Строк и ~ 600 столбцов. Все столбцы являются числовыми (десятичными (25, 6)). После полного заполнения вакуума «total_bytes», как сообщается в следующем запросе

select c.relname, pg_total_relation_size(c.oid) AS total_bytes 
from pg_class c; 

составляет около 150 МБ. Однако мы заметили, что это выросло до 71 ГБ в какой-то момент. В недавнем эпизоде ​​total_bytes увеличился на 10 ГБ за 30 минут.

Во время упомянутого выше эпизода у нас был пакетный запрос обновления, который запускается ~ 4 раза в минуту, который обновляет каждую запись в таблице. Однако в других случаях размер таблицы оставался неизменным, несмотря на аналогичные действия по обновлению.

Я понимаю, что это, вероятно, вызвано «мертвыми записями», оставшимися после обновлений. Действительно, когда эта таблица становится слишком большой, просто работающий вакуум полностью сжимает ее до нормального размера (150 М). Мои вопросы:

  • есть ли у других людей быстрый рост в размере стола в postgresql и это нормально?

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

    обновления my_table набора х = х * 2

, но не смогли - таблица размеров остались прежним до и после запроса.

+1

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

ответ

1

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

От PostgreSQL docs ...

Фактическая потребность в хранении [для числовых значений] два байта для каждой группы из четырех десятичных цифр, плюс 7:57 байты накладных расходов.

Так что decimal(25, 6) - это что-то вроде 8 + (31/4 * 2) или около 24 байт на столбец. В 600 столбцов на строку, что составляет около 14 400 байт в строке или 14k за строку. В 33 000 строк - около 450 мегабайт.

Если вы обновляете каждую строку 4 раза в минуту, это оставляет около 1,8 гигабайта в минуту мертвых рядов.

  1. Вы должны исправить свой дизайн схемы.
  2. Вам не нужно прикасаться к каждой строке таблицы 4 раза в минуту.

Вы должны задать вопрос о переделке этой таблицы и процесса.

+0

Другая проблема с таблицей с 600 столбцами заключается в том, что базовое хранилище ограничено ~ 8 кбайт в строке, поэтому, если вы на самом деле пытались поместить 25-значное число в каждый из этих столбцов, [он даже не подходит. .] (http://rextester.com/GAKZH12768) –

+0

Так почему я не могу воспроизвести эту проблему, запустив update table_name set x = x * 2, который обновляет каждую запись? – yan479

+0

@ yan479 Может быть, это вписывается в существующее хранилище, поэтому его не нужно перераспределять? Попробуйте установить его на случайные числа. Или, может быть, вам нужно заключить сделку? Или не в сделке? В любом случае, таблица плохо спроектирована, так что это похоже на то, чтобы узнать подробности о том, почему ваш летающий кирпич не летал. – Schwern

Смежные вопросы