Миграция `int` в` bigint` в PostgresSQL без простоев? - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть база данных, которая столкнется с проблемой целочисленного исчерпания , с которой Basecamp классно столкнулся еще в ноябре.У меня есть несколько месяцев, чтобы понять, что делать.

Существует ли не требующее простоя, упреждающее решение для миграции этого типа столбца?Если так, то, что это?Если нет, то нужно ли просто есть время простоя и перенести колонку, когда я могу?

Достаточно ли этой статьи , если у меня есть несколько дней / недель для выполнения миграции сейчас до того, как меня заставят это сделать, когда у меня закончатся идентификаторы?

Ответы [ 3 ]

0 голосов
/ 21 февраля 2019

Создать копию старой таблицы, но с измененным полем ID.Затем создайте триггер на старой таблице, который вставляет новые данные в обе таблицы.Наконец, скопируйте данные из старой таблицы в новую (было бы неплохо отличать данные перед запуском от пост-триггера, например, по id, если они последовательные).Как только вы закончите, переключите таблицы и удалите старую.

Это, очевидно, требует вдвое больше места (и времени для копирования), но будет работать без любого простоя.

0 голосов
/ 21 февраля 2019

Другое решение для баз данных до v10 , где все транзакции короткие :

  • Добавление столбца bigint в таблицу.

  • Создайте триггер BEFORE, который устанавливает новый столбец при каждом добавлении или обновлении строки.

  • Запуск серии обновлений, которые устанавливают новый столбец из староготот, где это IS NULL.Держите эти партии короткими, чтобы не блокировать долго и не блокировать много.Убедитесь, что эти транзакции выполняются с session_replication_role = replica, чтобы они не запускали триггеры.

  • После обновления всех строк создайте уникальный индекс CONCURRENTLY для нового столбца.

  • Добавьте уникальное ограничение USING индекс, который вы только что создали.Это будет быстро.

  • Выполните переключение:

    BEGIN;
    ALTER TABLE ... DROP oldcol;
    ALTER TABLE ... ALTER newcol RENAME TO oldcol;
    COMMIT;
    

    Это будет быстро.

Ваш новый столбецне установлен NOT NULLЭто не может быть сделано без длинной инвазивной блокировки.Но вы можете добавить проверочное ограничение IS NOT NULL и создать его NOT VALID.Это достаточно хорошо, и вы можете позже проверить его без сбоев.

Если есть ограничения внешнего ключа, все становится немного сложнее.Вы должны отбросить их и создать NOT VALID внешние ключи для нового столбца.

0 голосов
/ 21 февраля 2019

Использование логическая репликация .

С помощью логической репликации вы можете иметь разные типы данных на основном и резервном.

Скопировать схему с помощью pg_dump -s, изменить данныевведите копию и затем запустите логическую репликацию.

После того, как все данные скопированы, переключите приложение в режим ожидания.

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

Для этого вам нужен PostgreSQL v10 или выше, и ваша база данных не должна изменять схему, поскольку DDL не реплицируется.

...