Теперь Кью работает в режиме чтения

Мы сохранили весь контент, но добавить что-то новое уже нельзя

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

Data scienceАналитика+2
Анонимный вопрос
Data Science
  · 5,0 K
Openstack DevOps and IBM/Informix Certified DBA . Phd in Math (Duality of spaces of...  · 20 апр 2022
Информация ниже нуждается в тестированиии
==========================================
===========================================
Безопасные и небезопасные операции с большими объемами PostgreSQL
===========================================
PostgreSQL — это объектно-реляционная система управления базами данных, которую я часто использую для многих продуктов. Некоторые из этих продуктов должны иметь высокую доступность и работать без простоев. Это означает, что я должен выполнять миграцию схемы базы данных, пока приложение работает и обслуживает запросы. Я должен быть очень осторожен в отношении того, какие операции с базой данных я запускаю. Если я запускаю неверную команду, она может заблокировать обновления таблицы на долгое время. Например, если я создаю новый индекс для таблицы, я не могу создать новую запись в этой таблице, пока этот индекс строится. Любой, кто попытается внести запись в эту таблицу, будет заблокирован и, возможно, истечет время ожидания, что приведет к частичному отключению. В целом, я согласен с тем, что операции с базой данных занимают много времени. Однако любая операция, которая блокирует таблицу для обновлений более чем на несколько секунд, означает для меня время простоя.
============================================
Я решил составить список операций, которые можно сделать безопасно (без даунтайма) и небезопасно.
Добавить новый столбец (безопасный)
Эта операция не блокирует таблицу и может быть выполнена безопасно. Но существуют некоторые случаи, которые могут заблокировать вашу таблицу.
===========================================
Добавьте столбец со значением по умолчанию (небезопасно, если PostgreSQL < 11)
Добавление столбца со значением по умолчанию требует обновления каждой строки таблицы (для сохранения нового значения столбца). Для большой таблицы это создаст длительную операцию, которая ее заблокирует. Поэтому, если вы намереваетесь заполнить столбец в основном значениями, отличными от значений по умолчанию, лучше всего добавить столбец без значений по умолчанию, вставить правильные значения с помощью UPDATE (правильный способ — выполнять пакетные обновления, например, обновлять 1000 строк за раз, потому что большое обновление создаст блокировку для всей таблицы), а затем добавьте любое желаемое значение по умолчанию.
==============================================
ОБНОВЛЕНИЕ: в PostgreSQL 11 теперь можно использовать такие операторы DDL:
==============================================
ALTER TABLE users ADD COLUMN foo_factor integer NOT NULL DEFAULT 42;
выполняться за постоянное время. Строки не затрагиваются, когда это выполняется, а вместо этого обновляются «лениво».
Добавьте столбец, который не может быть нулевым (небезопасно, если PostgreSQL < 11)
Это будет иметь ту же проблему, что и «Добавить столбец со значением по умолчанию». Чтобы сделать эту операцию без блокировки, вы можете создать новую таблицу с добавлением ненулевого столбца, записать в обе таблицы, выполнить обратное заполнение, а затем переключиться на новую таблицу. Этот обходной путь невероятно обременительный и требует в два раза больше места, чем занимает таблица.
===========================================
ОБНОВЛЕНИЕ: в PostgreSQL 11 теперь можно использовать такие операторы DDL:
ALTER TABLE users ADD COLUMN foo_factor integer NOT NULL DEFAULT 42;
выполняться за постоянное время. Строки не затрагиваются, когда это выполняется, а вместо этого обновляются «лениво».
Смотри также https://dba.stackexchange.com/questions/211221/add-column-with-default-in-postgresql-without-table-lev... Читать дальше
Пишу код и т.п.  · 20 апр 2022  · itustinov.ru
Никак. Добавление колонки требует блокировки таблицы. Если есть долгие запросы, которые занимают таблицу, их можно принудительно остановить, но если это прод, у пользователей и у подключенного приложения могут возникнуть проблемы. -- В старых версиях PID назывался PROCPID. -- Исключаем подключения и свой только что -- вызванный процесс. SELECT pid, query_start, state... Читать далее