Особенности работы команд 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
могут завершиться ошибкой, сохраните вывод запроса в файл и попробуйте заново повторить каждый этап.