Использование Postgres 10,6
Вопрос:
- Некоторые данные в моих таблицах нарушают ограничения внешнего ключа (не знаю, как). Ограничения:
ON DELETE CASCADE ON UPDATE CASCADE
- В pg_dump базы данных эти внешние ключи удаляются (из-за того, что они находятся в недопустимом состоянии?)
- A
pg_restore
превращается в пустую базу данных, в которой больше нет внешних ключей
- В новой базе данных все ее первичные ключи обновлены до допустимых ключей, не используемых во второй базе данных. Таблицы с недействительными данными не обновляют свои внешние ключи из-за отсутствующего ограничения.
- A
pg_dump
новой базы данных завершено, затем база данных удалена
- На
pg_restore
во второй базе данных, которая имеет ограничения внешнего ключа, данные импортируются в недопустимом состоянии и повреждают новую базу данных.
Я хочу сделать следующее: каждые несколько часов (или один раз в день, в зависимости от того, сколько времени займет запрос), чтобы убедиться, что все данные во всех таблицах, которые имеют внешние ключи, действительны.
Я прочитал о ALTER TABLE ... VALIDATE CONSTRAINT ...
, но это не решило бы мою проблему, так как данные в настоящее время не помечены как NOT VALID
. Я знаю, что может сделать такие заявления, как:
DELETE FROM a WHERE a.b_id NOT IN ( SELECT b.id )
Однако у меня 144 таблицы с внешними ключами, так что это было бы довольно утомительно. Возможно, я бы также не хотел немедленно удалять данные, но регистрировал проблему и информировал пользователя об исправлении, которое произойдет.
Конечно, я хотел бы знать, как произошла первоначальная коррупция, и предотвратить это; однако в данный момент я просто пытаюсь предотвратить его распространение.
Пример таблицы:
CREATE TABLE dependencies (
...
from_task int references tasks(id) ON DELETE CASCADE ON UPDATE CASCADE NOT NULL,
to_task int references tasks(id) ON DELETE CASCADE ON UPDATE CASCADE NOT NULL,
...
);
Зависимости будут заканчиваться значениями to_task
и from_task
, которых нет в таблице tasks
(см. Изображение)
Примечание:
- попробовал
EXPLAIN
ANALYZE
ничего странного
- pg_tablespace, имеет только две записи. pg_default и pg_global
- relforcerowsecurity, relispartition оба «ложны» в обеих таблицах
- Аргументы в pg_dump (из вызова c ++)
arguments << "--file=" + fileName << "--username=" + connection.userName() << databaseName << "--format=c"