Перенос PostgreSQL на другой сервер: дамп, роли и проверка

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

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

Когда подходит перенос через дамп

Разберём перенос одной базы PostgreSQL 16 на другой сервер той же основной версии. Есть доступ к исходной базе, место под копию и согласованное время остановки записи. Это не перенос всего приложения: файлы, очереди, настройки и внешние подключения проверяются отдельно.

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

Что проверить до остановки приложения

  • Версии сервера, pg_dump и pg_restore. Старый pg_dump не умеет выгружать более новый сервер. Для этого примера используйте клиентские утилиты PostgreSQL 16.
  • Размер базы, свободное место и время пробного восстановления. Небольшой архив может потребовать значительно больше места после распаковки и создания индексов.
  • Расширения, кодировки, локали, владельцев объектов и права. На новой площадке должны быть доступны нужные расширения и совместимые настройки.
  • Все источники записи: приложение, фоновые задачи, импорты, интеграции и прямые подключения. Остановка сайта не всегда останавливает запись в базу.
pg_dump --version
pg_restore --version
psql -X --host=db-old.internal --username=app --dbname=app \
  --command="SHOW server_version;"
psql -X --host=db-old.internal --username=app --dbname=app \
  --command="SELECT extname, extversion FROM pg_extension ORDER BY extname;"

Имена серверов, пользователей и баз здесь условные. Подставьте свои. Подключайтесь по защищённой сети, через настроенный SSH-туннель или с TLS по требованиям площадки. Пароль вводите по запросу клиента либо храните в заранее настроенном защищённом файле паролей. Не вставляйте его в команду или репозиторий.

Сначала сделайте репетицию

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

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

Сделайте финальный дамп

umask 077
pg_dump --host=db-old.internal --username=app --dbname=app \
  --format=custom --file=app-final.dump
pg_restore --list app-final.dump > app-final.contents.txt

Проверьте код завершения pg_dump и сообщения об ошибках. Наличие файла само по себе ничего не доказывает. Список содержимого показывает, что архив читается, но не заменяет восстановление.

pg_dump получает согласованный снимок базы. Изменения, записанные после начала этого снимка, в него не попадут. Поэтому команда сама по себе не решает задачу переезда без потери новых заказов.

Один дамп базы не создаёт все роли и табличные пространства кластера. Их перенос планируют отдельно. В примере ниже объекты будут принадлежать одной роли app, а прежние владельцы и права из дампа не применяются. Для системы с несколькими ролями это решение нельзя переносить автоматически.

Подготовьте новую базу и восстановите данные

На новой площадке администратор создаёт роль app, если её ещё нет, и отдельную пустую базу. Пароль новой роли задаётся интерактивно. При наличии готовой роли проверьте её права, не создавайте повторно.

createuser --host=db-new.internal --username=db_admin --pwprompt app
createdb --host=db-new.internal --username=db_admin \
  --owner=app --template=template0 app_migrated
pg_restore --host=db-new.internal --username=app --dbname=app_migrated \
  --no-owner --no-acl --exit-on-error --single-transaction app-final.dump

У app должны быть права на создание объектов в новой базе. Расширения, требующие повышенных прав, заранее готовит администратор. Не выдавайте приложению superuser только ради обхода ошибки.

Здесь --no-owner и --no-acl сознательно отключают восстановление старых владельцев и разрешений. Это удобно для одной роли в учебном примере, но права остальных пользователей нужно воссоздать и проверить отдельно. --single-transaction делает восстановление одним целым: при ошибке изменения этой попытки откатываются.

Проверьте данные и подключение приложения

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

Сверьте важные таблицы, последние записи и суммы, значимые для проекта. В учебной базе с таблицей orders можно сравнить такой результат на старой и новой стороне:

SELECT count(*) AS rows, max(id) AS last_id, sum(total) AS total
FROM public.orders;

Это пример проверки, а не универсальное доказательство равенства баз. Одинаковое количество строк не означает одинаковое содержимое. Для вашего проекта могут понадобиться дополнительные сверки.

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

Переключите запись и сохраните возможность разобраться

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

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

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

Источники и границы примера

Поведение форматов и параметров сверено с документацией pg_dump, pg_restore и руководством по SQL Dump. Пример рассчитан на одну базу и одного владельца объектов. Это не инструкция по переносу сложного кластера без остановки.

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

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

Да, pg_dump создаёт согласованный снимок. Но новые изменения после начала снимка не попадут в этот дамп. Для финального переключения нужно согласовать остановку записи или другой способ синхронизации.

Перенесутся ли пользователи и все права автоматически?

Нет. Дамп одной базы не создаёт все роли кластера. В этом примере старые владельцы и права отключены, объекты создаются под ролью app. Систему с несколькими ролями нужно разбирать отдельно.

Можно ли сразу отключить старый сервер?

Сначала проверьте данные, приложение и новые записи. Старую площадку отключают после согласованной проверки и решения о хранении копий.

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

Перенос рабочей базы можно поручить мне и команде. Если задача шире одной базы, разберём и остальные части проекта. Обсудить перенос данных.