Перейти к основному содержимому

Особенности работы команд ATTACH/DETACH PARTITION в СУБД Pangolin 7.1

Если целевая таблица секционирована, то для отдельной, ссылающейся на целевую, таблицы необходимы другие записи каталога. В версиях PostgreSQL до 15.9 команды ATTACH/DETACH PARTITION выполняли это преобразование некорректно. В частности, после выполнения команды DETACH для новой отдельной таблицы терялись триггеры обеспечения целостности внешнего ключа, из-за чего в таблице могли появляться строки, не выполняющие требования по ограничению внешнего ключа. Кроме того, последующее повторное присоединение командой ATTACH могло приводить к неожиданным ошибкам.

Это можно исправить, выполнив команду ALTER TABLE DROP CONSTRAINT для новой отдельной таблицы в отношении каждого ограничения с ошибкой и добавив ограничение заново. Ошибка при повторном добавлении ограничения означает появление ошибочных данных. В этом случае необходимо заново и вручную обеспечить целостность целевой и ссылающейся таблиц, а затем еще раз добавить ограничение.

Примечание

Команда TRUNCATE PERTITION CASCADE применительно к родительской секционированной таблице приведет к полному удалению данных также и из дочерних таблиц.

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

SELECT conrelid::pg_catalog.regclass AS "constrained table",
conname AS constraint,
confrelid::pg_catalog.regclass AS "references",
pg_catalog.format('ALTER TABLE %s DROP CONSTRAINT %I;',
conrelid::pg_catalog.regclass, conname) AS "drop",
pg_catalog.format('ALTER TABLE %s ADD CONSTRAINT %I %s;',
conrelid::pg_catalog.regclass, conname,
pg_catalog.pg_get_constraintdef(oid)) AS "add"
FROM pg_catalog.pg_constraint c
WHERE contype = 'f' AND conparentid = 0 AND
(SELECT count(*) FROM pg_catalog.pg_constraint c2
WHERE c2.conparentid = c.oid) <>
(SELECT count(*) FROM pg_catalog.pg_inherits i
WHERE (i.inhparent = c.conrelid OR i.inhparent = c.confrelid) AND
EXISTS (SELECT 1 FROM pg_catalog.pg_partitioned_table
WHERE partrelid = i.inhparent));

Поскольку один или несколько этапов выполнения команды ADD CONSTRAINT могут завершиться ошибкой, сохраните вывод запроса в файл и попробуйте заново повторить каждый этап.