pg_dump -h host -U postgres -d shop -Fc -f shop.dump снимает сжатый дамп, а pg_restore -d shop_copy shop.dump возвращает его обратно. Но до этого всего клиент должен быть не старше сервера: pg_dump младшей версии просто отказывается работать, и именно эта ошибка чаще всего оставляет базу без бэкапа.
1. Ошибка, на которой всё останавливается
$ 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 сними дамп базы shop в бинарный файл→ pg_dump -h pg17 -U postgres -d shop -Fc -f shop.dump
-Fc пишет сжатый архив, из которого pg_restore умеет доставать отдельные объекты и грузить их в несколько потоков через -j. Обычный .sql не умеет ни того, ни другого — он вливается в psql целиком и по порядку.
3. Заглянуть внутрь до восстановления
$ 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 восстанови дамп в базу shop_copy→ pg_restore -h pg17 -U postgres -d shop_copy shop.dump
База должна существовать заранее — createdb shop_copy, — потому что без -C pg_restore её не создаст. При успехе команда не печатает ничего, так что проверяйте через select count(*).
5. Одна таблица, только данные
$ 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 восстанови дамп поверх существующей базы→ 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 пишет команды дампа и восстановления с нужными флагами и показывает их до того, как хоть одна из них коснётся базы. Поставить одной строкой.