Восстановление PostgreSQL из дампа: pg_restore и psql

Файл копии есть. Теперь нужно понять его формат, восстановить базу отдельно от рабочей системы и проверить, что приложение сможет с ней работать.

Автор — Дмитрий Тыльный · опыт Senior DevOps · 16 октября 2026 · 8 мин

Сначала определите, какая копия у вас есть

Расширение .backup или .dump не определяет содержимое файла. У PostgreSQL есть обычный SQL, custom-архив, tar и каталог с файлами. Физическая копия каталога данных и набор WAL — другие способы восстановления, к которым эти команды не подходят.

file app.dump
pg_restore --list app.dump > app.contents.txt

Если pg_restore выводит состав архива, для него подходит pg_restore. Если сообщает о текстовом формате, нужен psql. Любую другую ошибку не трактуйте как разрешение попробовать другой инструмент: файл может быть повреждён, обрезан или создан более новой версией утилиты.

Сохраните исходный файл без изменений. Восстанавливайте только копию из доверенного источника: дамп содержит команды SQL и может выполнять действия в целевой системе. Для проверки используйте отдельную базу и нужные для неё права.

Проверьте версии, роли и расширения

Дальше — пример для PostgreSQL 16. Клиент pg_restore должен понимать формат архива, а целевой сервер — объекты и команды, которые в нём находятся. Восстановление на более старую основную версию нельзя считать обычной совместимой операцией.

  • Уточните версию исходной базы и клиента, которым сделана копия.
  • Проверьте расширения и их наличие на новой площадке.
  • Определите владельцев объектов, права приложения и кодировку базы.
  • Оцените свободное место. Данные, индексы и временные операции требуют больше места, чем сжатый файл.

Условные db-new.internal, db_admin и app замените своими значениями. Роль app уже должна существовать. Как подготовить её и новую площадку, разобрано в инструкции по переносу PostgreSQL. Пароли не передавайте в тексте команды.

Создайте отдельную пустую базу

createdb --host=db-new.internal --username=db_admin \
  --owner=app --template=template0 app_restore

Имя app_restore здесь выбрано специально, чтобы не восстанавливать поверх рабочей базы. Если такая база уже есть после неудачной попытки, выясните её состояние и создайте другую пустую. Не добавляйте --clean к случайной команде в надежде, что всё исправится.

Учебный пример рассчитан на одного владельца. Если в исходной системе несколько ролей, отдельные схемы и особые разрешения, заранее составьте их соответствие на новой стороне. Отключение восстановления старых прав не делает новую систему безопасной автоматически.

Восстановите custom, tar или каталог через pg_restore

pg_restore --host=db-new.internal --username=app --dbname=app_restore \
  --no-owner --no-acl --exit-on-error --single-transaction app.dump

Для копии в формате каталога вместо app.dump укажите путь к этому каталогу. --exit-on-error прекращает восстановление при первой ошибке. --single-transaction позволяет откатить изменения этой попытки, если команда завершилась с ошибкой. Параллельное восстановление с --jobs в этот пример не входит.

--no-owner и --no-acl означают, что прежние владельцы и разрешения не применяются. Объекты создаются под текущей ролью. Если нужно сохранить исходную модель доступа, эти параметры и состав ролей выбирают по другому плану.

Для обычного SQL используйте psql

psql -X --host=db-new.internal --username=app --dbname=app_restore \
  --set=ON_ERROR_STOP=on --single-transaction --file=app.sql

-X отключает настройки из пользовательского psqlrc, ON_ERROR_STOP останавливает выполнение при SQL-ошибке. Транзакционный режим подходит для обычного дампа одной базы без команд, запрещённых внутри транзакции. Файл с CREATE DATABASE, собственными переключениями подключения или посторонними командами сначала нужно разобрать.

Если SQL сжат gzip, сначала проверьте и распакуйте его в отдельный файл. Только после успешного завершения обеих команд запускайте psql:

gzip --test app.sql.gz
gzip --decompress --stdout app.sql.gz > app.sql

Не считайте обрыв распаковки нормальным окончанием SQL. Даже если часть таблиц появилась, это ещё не восстановленная база. После ошибки проверяйте причину и повторяйте восстановление в чистой отдельной базе.

Что означают частые ошибки

  • role does not exist. В копии есть ссылка на роль, которой нет в новом кластере. Проверьте владельцев, разрешения и выбранный способ переноса ролей.
  • permission denied. У текущей роли не хватает нужного права. Найдите конкретный объект или операцию, а не выдавайте приложению superuser наугад.
  • extension is not available. Проверьте установку и версию расширения на сервере. Одного файла дампа для внешнего расширения может быть недостаточно.
  • already exists. Целевая база может быть не пустой. Не смешивайте результат двух попыток.
  • unsupported version in file header. Проверьте версию pg_restore и целостность архива. Переименование файла не меняет его формат.

Проверьте базу, а затем приложение

psql -X --host=db-new.internal --username=app --dbname=app_restore \
  --command="SELECT current_database(), current_user;"
psql -X --host=db-new.internal --username=app --dbname=app_restore \
  --command="ANALYZE;"

Сверьте ключевые таблицы, последние записи, последовательности и права. Если есть сведения с исходной стороны, сравните их с результатом. Одно количество строк не подтверждает полное совпадение.

Подключайте тестовую копию приложения с отключёнными письмами, платежами и другими внешними действиями. Проверьте чтение, запись, загрузки и фоновые задачи. База может восстановиться без ошибок, а приложение — не запуститься из-за файлов, секретов или расширений.

Возраст копии — это ещё и возможная потеря изменений. Дамп не содержит всю историю до настоящего момента. Для возврата на произвольную точку времени нужны подходящий способ резервирования и необходимые журналы. Полный процесс разобран в проверке восстановления проекта.

Источники

Форматы архивов и параметры описаны в справке pg_restore. Порядок работы с SQL и проверками ошибок — в руководстве PostgreSQL по SQL Dump. Команды относятся к отдельной тестовой базе, а не к произвольной рабочей системе.

Частые вопросы

Чем восстановить файл .dump?

Сначала определите формат. Custom, tar и каталог восстанавливают через pg_restore, обычный SQL — через psql. Расширение файла само по себе формат не подтверждает.

Можно ли восстановить дамп поверх рабочей базы?

Для проверки создайте отдельную пустую базу. Восстановление поверх рабочей системы требует отдельного плана, согласованной остановки и защиты текущих данных.

Почему приложение не работает после успешного восстановления?

Помимо таблиц нужны правильные подключения, роли, права, расширения, файлы и секреты. Проверка восстановления включает запуск приложения и действия пользователя.

Если нужна помощь с проектом

Если с восстановлением базы нужна помощь, можно обратиться ко мне. С командой проверим доступную копию, состояние проекта и то, что нужно для запуска. Обсудить восстановление проекта.