CLI AI

pg_dump и pg_restore без ловушки версий

2026-07-23

pg_dump -h host -U postgres -d shop -Fc -f shop.dump снимает сжатый дамп, а pg_restore -d shop_copy shop.dump возвращает его обратно. Но до этого всего клиент должен быть не старше сервера: pg_dump младшей версии просто отказывается работать, и именно эта ошибка чаще всего оставляет базу без бэкапа.

1. Ошибка, на которой всё останавливается

clai
$ clai сними дамп базы shop с сервера pg17→ pg_dump -h pg17 -U postgres -d shoppg_dump: error: aborting because of server version mismatchpg_dump: detail: server version: 17.10; pg_dump version: 16.14 (Debian 16.14-1.pgdg13+1)

Флагом это не лечится. Нужен клиент подходящей версии — пакет postgresql-client-17 или просто тот же образ контейнера, что и у сервера. Обратная комбинация работает: клиент новее сервера снимет дамп спокойно.

2. Дамп в custom-формате, а не в .sql

clai
$ clai сними дамп базы shop в бинарный файл→ pg_dump -h pg17 -U postgres -d shop -Fc -f shop.dump

-Fc пишет сжатый архив, из которого pg_restore умеет доставать отдельные объекты и грузить их в несколько потоков через -j. Обычный .sql не умеет ни того, ни другого — он вливается в psql целиком и по порядку.

3. Заглянуть внутрь до восстановления

clai
$ clai покажи что лежит внутри дампа→ pg_restore -l shop.dump218; 1259 16386 TABLE public orders postgres217; 1259 16385 SEQUENCE public orders_id_seq postgres3427; 0 0 SEQUENCE OWNED BY public orders_id_seq postgres3271; 2604 16389 DEFAULT public orders id postgres3420; 0 16386 TABLE DATA public orders postgres

Это оглавление. Сохраните его в файл, вычеркните ненужные строки и скормите обратно через -L — так делают выборочное восстановление по-человечески.

4. Восстановить в другую базу

clai
$ clai восстанови дамп в базу shop_copy→ pg_restore -h pg17 -U postgres -d shop_copy shop.dump

База должна существовать заранее — createdb shop_copy, — потому что без -C pg_restore её не создаст. При успехе команда не печатает ничего, так что проверяйте через select count(*).

5. Одна таблица, только данные

clai
$ clai выгрузи только таблицу orders без схемы→ pg_dump -h pg17 -U postgres -d shop -t orders --data-only -f orders-data.sql

-t сужает выгрузку до одного объекта, --data-only убирает CREATE TABLE. Удобно, когда таблица на приёмнике уже есть в том же виде и нужны только строки.

6. Восстановление поверх непустой базы

clai
$ clai восстанови дамп поверх существующей базы→ pg_restore -h pg17 -U postgres -d shop_copy --clean --if-exists shop.dump

Без --clean тот же дамп во второй раз падает с pg_restore: error: could not execute query: ERROR: relation "orders" already exists. --clean удаляет объекты перед созданием, а --if-exists глушит ошибки на тех, которых ещё нет.

Gotchas

  • Клиент старше сервера не снимет дамп вообще. Проверено: pg_dump 16.14 против сервера 17.10 останавливается сразу. Держите клиент не старше сервера; в контейнерном мире проще всего запускать pg_dump из того же образа, что и сервер.
  • pg_restore -t дописывает, а не заменяет. Восстановление одной таблицы в базу, где она уже с данными, даёт ERROR: duplicate key value violates unique constraint "orders_pkey". Сначала truncate, потом restore.
  • pg_restore возвращает 0 даже после ошибок. Проверено: при конфликте ключей он напечатал ошибку и всё равно завершился с кодом 0. В скриптах добавляйте --exit-on-error, иначе сломанное восстановление выглядит успешным.

Related questions

Как снять дамп только схемы? pg_dump --schema-only даёт структуру без строк. --data-only — зеркальный вариант.

Чем восстанавливать .sql-дамп? psql -d база -f dump.sql. pg_restore понимает только форматы -Fc, -Fd и -Ft, обычный текст в этот список не входит.

Как ускорить восстановление большой базы? pg_restore -j 4 грузит данные и строит индексы параллельно. Работает только с custom и directory форматами.

See also

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