Как обеспечить действительность внешних ключей в Postgres - PullRequest
0 голосов
/ 09 января 2019

Использование 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 (см. Изображение)

enter image description here

Примечание:

  • попробовал EXPLAIN ANALYZE ничего странного
  • pg_tablespace, имеет только две записи. pg_default и pg_global
  • relforcerowsecurity, relispartition оба «ложны» в обеих таблицах
  • Аргументы в pg_dump (из вызова c ++) arguments << "--file=" + fileName << "--username=" + connection.userName() << databaseName << "--format=c"

1 Ответ

0 голосов
/ 09 января 2019

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

pg_dump никогда не будет молча «отбрасывать» ограничение & mdash; возможно, произошла ошибка при восстановлении дампа, который вы не заметили.

Правильное исправление - очистить данные, которые нарушают ограничение, и заново создать их.

Если это проблема с повреждением данных, проверьте ваше оборудование.

Нет необходимости регулярно проверять наличие данных, PostgreSQL не имеет привычки портить данные самостоятельно.

Лучшим тестом было бы регулярно pg_dump проверять, не вызывает ли восстановление дампа какие-либо ошибки.

...