Восстановление PostgreSQL db из резервной копии без проблемы ограничения внешнего ключа

у меня есть БД postgresql с таблицами 85+. Я делаю резервные копии регулярно используя pg_dump (через php-pgadmin) в режиме копирования и размер файла резервной копии составляет почти 10-12 МБ. Теперь проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда я пытаюсь восстановить базу данных, возникает проблема ограничения внешнего ключа. Сценарий выглядит следующим образом:

есть две таблицы: 1) users и 2) zones. Я сохранил идентификатор зоны в users таблица для идентификации зоны пользователя и установки ее как внешней ключ.

когда я беру дамп БД, записи в таблице zones приходите только после таблицы users. Я думаю, это связано с первой буквой названия таблицы:u перед z, и поэтому при восстановлении базы данных возникает проблема ограничения внешнего ключа и выполнение останавливается. Та же проблема возникает, когда я пытаюсь восстановить структуру БД, она говорит, что таблица zones не существует в базе данных, так как структура zones идет после users in файл дампа.

есть ли решение для этого? Существует ли какой-либо другой метод резервного копирования?

5 ответов


звучит так, как будто вы получаете дамп SQL, а не двоичный дамп из pg_dump. Это даст вам большую кучу SQL со схемой (включая FKs) вверху, а затем кучу вставок для перезагрузки данных. Двоичный дамп из pg_dump будет служить вам лучше, похоже, вам нужно немного дополнительной конфигурации, чтобы сказать PhpPgAdmin, где pg_dump есть. Тогда вы бы скормили этот двоичный дамп в pg_restore и pg_restore перестроил бы все в правильном порядке, чтобы избежать проблемы ссылочной целостности (или, точнее,pg_restore восстановит все данные, а затем добавит ограничения).

PhpPgAdmin, похоже, хочет работать с обычными SQL-дампами, а не pg_restore. Мне трудно в это поверить, но я не могу найти ничего в документации о вызове pg_restore. Если это правда, вам, вероятно, придется вручную отредактировать дамп SQL и переместить все FKs в конец.

вы также можете попробовать добавить SET CONSTRAINTS ALL DEFERRED; в верхней части дампа SQL, который должен задерживать проверку ограничений до конца транзакции, вы также захотите убедиться, что весь блок вставок содержится в транзакции.

если PhpPgAdmin действительно не может вызвать pg_restore тогда вам лучше использовать using pg_dump и pg_restore вручную, чтобы у вас был необходимый контроль над процедурами резервного копирования. Извините, но любой инструмент администрирования базы данных, который не может обрабатывать резервное копирование базы данных с ФКС хуже, чем бесполезно. Надеюсь, кто-то, кто знает свой путь вокруг PhpPgAdmin появится и сообщите нам, как использовать pg_restore С PhpPgAdmin.


Если это кому-то помогает: ни одно из предыдущих предложенных решений не работало для меня (были некоторые вставки, сделанные со ссылками на данные, которые были сброшены позже, независимые, если они были в двоичном формате или простые SQL-запросы).

Что я сделал: я использовал schemaspy, скрипт, который-среди других функций, таких как действительно полезная html-диаграмма базовой модели ER-генерирует два очень полезных списка: "порядок вставки" (где все ваши таблицы перечислены как оптимальные порядок выполнения вставок с учетом существующих ограничений и зависимостей) и "порядок удаления" (очень полезный для удаления таблиц).

Если вы хотите образец, проверьте это http://schemaspy.sourceforge.net/sample/. В частности, есть два примера списков, которые я упомянул выше (пытался опубликовать прямые ссылки, но механизм предотвращения спама позволяет мне размещать только 2 ссылки).


использование pgdump (через php-pgadmin)

вы уверены, что PhpPgAdmin использует pg_dump для создания резервных копий? Я никогда не видел дампа, созданного pg_dump, с проблемами с внешними ключами при восстановлении дампа.

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


Я бы удалил создание fk спереди и добавил его в конец скрипта.


я обнаружил, что вы можете добавить в начале sql (это остановит проверки внешнего ключа):

SET session_replication_role = replica;

и в конце (для восстановления проверок):

SET session_replication_role = origin;