Как добавить ненулевой столбец в таблицу postgresql, не удваивая его размер на диске - PullRequest
3 голосов
/ 18 января 2010

Есть ли способ добавить столбец ненулевого типа в таблицу Postgresql, не удваивая его размер на диске? Например, если у меня есть таблица с определенными столбцами, и я хочу добавить столбец, я бы сделал следующее:

alter table my_table add new_column int  
update table my_table set new_column = 0 
alter table my_table alter column new_column set not null

Это фактически удваивает пространство, выделенное для таблицы, из-за того, как работает Postgresql. Обновления создают новые кортежи, которые будут помечены для повторного использования после завершения этой транзакции и выполнения своей работы вакуумом. Если таблица имеет большой размер (т. Е. Несколько миллионов строк), но очень медленно растет или почти постоянна по размеру, эти строки никогда не будут использоваться повторно, и только «полное заполнение пылесосом» или полное резервное копирование и восстановление базы данных освободит место на диске. Есть ли способ автоматически добавить столбец с некоторым значением по умолчанию, но без этого поведения? Например, если есть способ заблокировать таблицу и выполнить обновление, тогда в этом случае не будет необходимости в MVCC.

Ответы [ 2 ]

4 голосов
/ 18 января 2010

делайте это поэтапно:

  1. изменить таблицу добавить новый столбец
  2. изменить таблицу добавить значение по умолчанию для столбца
  3. обновить, но не всю таблицу с 1 оператором обновления, но выпустить ее примерно в 10000 отдельных обновлений, каждое в своей собственной транзакции
  4. запускать пылесос каждые пару сотен обновлений или лучше - автовакуум
  5. изменить набор таблиц не нуль
0 голосов
/ 19 января 2010

Если таблица имеет большой размер (т. Е. Несколько миллион строк) но очень медленно растет или почти постоянен в размере тех, строки никогда не будут использованы повторно, а только «вакуум заполнен» или полная база данных резервное копирование и восстановление освободит пространство на диске.

Это кажется подозрительным. Интересно, если ваша карта свободного пространства недостаточно велика - когда это происходит, postgres начинает терять следы удаленных строк и не может восстановить их, кроме как с полным вакуумом. Если вы используете Postgres <= 8.3, проверили ли вы, чтобы ваши max_fsm_pages были достаточно большими, чтобы отслеживать удаленные строки? Чтобы выяснить это, сделайте все возможное, чтобы добраться до этого состояния, когда в таблице есть мертвые строки, которые не используются повторно, а затем выполните «полный вакуум». Postgres расскажет вам о проблемах с FSM в конце вакуума. </p>

max_fsm_pages ушел с Postgresql 8.4. Если у вас 8.4, не берите в голову.

...