Pg_repack таблица без уникального ключа - PullRequest
0 голосов
/ 19 марта 2020

У меня есть проблема ниже: у меня есть таблица, конечно, на продукт ... Когда-то, прежде чем мы столкнулись с лимитом INT pk, поэтому мы просто изменим его на -1 по умолчанию. Теперь я хочу запустить на нем pg_repack, но для этого нужно иметь не NULL, а уникальный ключ. Есть ли у вас опыт с этим? Мои варианты: 1. Вакуум полный. Не может, потому что воздействие. 2. Добавьте несколько дополнительных уникальных столбцов, это может занять некоторое время и оказать влияние. Также может сломать select * запросы. 3. Добавьте столбец со значением по умолчанию, затем обновите его серийным номером и отметьте как уникальный. Никогда раньше не пробовал. AWS RDS.

1 Ответ

0 голосов
/ 19 марта 2020

Производительность всегда будет зависеть, ваша цель - сделать ACCESS EXCLUSIVE блокировки как можно короче.

Итак

  • добавить столбец bigint без значения по умолчанию

  • создать последовательность OWNED BY новый столбец

  • использовать ALTER TABLE для установки значения по умолчанию для столбца с помощью последовательность

  • обновляет значения NULL в новом столбце из последовательности

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

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

  • добавить уникальное ограничение с использованием нового индекса

Это не даст вам первичный ключ, потому что вы все еще пропускаете ограничение NOT NULL. Невозможно установить столбец NOT NULL без сканирования всей таблицы, которая будет удерживать блокировку ACCESS EXCLUSIVE в течение более длительного времени. Однако, если вам нужен истинный первичный ключ, вы не можете этого избежать.

Вот моя процедура в SQL с использованием примера таблицы:

ALTER TABLE x ADD id bigint;

CREATE SEQUENCE x_id_seq OWNED BY x.id;

ALTER TABLE x ALTER id SET DEFAULT nextval('x_id_seq');

UPDATE x SET id = nextval('x_id_seq')
WHERE id IS NULL
  AND somecol BETWEEN 1 AND 10000;
UPDATE x SET id = nextval('x_id_seq')
WHERE id IS NULL
  AND somecol BETWEEN 10001 AND 20000;
...

CREATE UNIQUE INDEX CONCURRENTLY x_id_idx ON x(id);

ALTER TABLE x ADD UNIQUE USING INDEX x_id_idx;

Я надеюсь, что в следующий раз вы узнаете лучше, и вы никогда больше не создадите таблицу без первичного ключа.

...