Как добавить столбец в таблицу на продакшене PostgreSQL без простоев?

Здесь https://stackoverflow.com/a/53016193/10894456 приведен ответ для Oracle 11g. Мой вопрос такой же:

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

а для PostgreSQL?


person J.J. Beam    schedule 29.04.2020    source источник


Ответы (1)


Этот предыдущий ответ по существу отвечает на ваш запрос.

Перекрестные ссылки на соответствующий документ PostgreSQL с исходным кодом PostgreSQL для AlterTableGetLockLevel, упомянутый в приведенном выше ответе, показывает, что ALTER TABLE ... ADD COLUMN всегда будет получать блокировку таблицы ACCESS EXCLUSIVE, препятствующую доступу любой другой транзакции к таблице на время операции ADD COLUMN. Такая же монопольная блокировка получается для любой ADD COLUMN вариации; т.е. не имеет значения, добавляете ли вы столбец NULLDEFAULT или без него) или имеете NOT NULL со значением по умолчанию.

Однако, как упоминалось в связанном ответе выше, добавление столбца NULL без DEFAULT должно быть очень быстрым, поскольку эта операция просто обновляет каталог.

Напротив, добавление столбца со спецификатором DEFAULT требует перезаписи всей таблицы в PostgreSQL 10 или более ранней версии. Эта операция, вероятно, займет значительное время в вашей таблице записей 1M. Согласно связанному ответу, PostgreSQL ›= 11 не требует такой перезаписи для добавления такого столбца, поэтому он должен работать более похоже на случай no-DEFAULT.

Я должен добавить, что для PostgreSQL 11 и выше ALTER TABLE docs обратите внимание, что перезаписи таблицы избегают только для энергонезависимых спецификаторов DEFAULT:

Когда столбец добавляется с помощью ADD COLUMN и указывается энергонезависимое значение DEFAULT, во время оператора оценивается значение по умолчанию, а результат сохраняется в метаданных таблицы. Это значение будет использоваться для столбца для всех существующих строк. Если значение DEFAULT не указано, используется NULL. Ни в том, ни в другом случае переписывание таблицы не требуется.

Добавление столбца с изменяемым значением DEFAULT [...] потребует перезаписи всей таблицы и ее индексов. [...] Перестроение таблицы и/или индекса может занять значительное время для большой таблицы; и временно потребуется вдвое больше места на диске.

person Timshel    schedule 30.04.2020
comment
Именно так. Начиная с версии 11 это невероятно быстро. Ему по-прежнему требуется короткая блокировка ACCESS EXCLUSIVE, так как определение таблицы меняется. Если это разрушительно или не зависит от параллельной активности: длительные транзакции вызовут проблемы (как всегда). - person Laurenz Albe; 30.04.2020