PostgreSQL в Docker: pg_dump, восстановление и проверка резервной копии
Автор: Казачкин Даниил Михайлович · Обновлено
Docker volume сохраняет файлы после удаления контейнера, но не защищает от ошибочного SQL, повреждения или удаления самого тома. Резервная копия становится полезной, когда из неё удалось восстановить данные и проверить результат. В этом уроке создадим отдельный учебный PostgreSQL 17, сделаем логический dump и восстановим его в новую базу, не затрагивая исходную.
Изолированное окружение
Понадобятся Docker и Bash на Linux либо в WSL. Используйте свободные имена dk-pg-backup и dk-pg-backup-data. Не запускайте команды в контейнере рабочей базы. Пароль ниже относится только к одноразовому упражнению; порт на хост не публикуется.
docker volume create dk-pg-backup-data
docker run -d --name dk-pg-backup -e POSTGRES_USER=lesson -e POSTGRES_PASSWORD=training-only -e POSTGRES_DB=source_db --mount type=volume,src=dk-pg-backup-data,dst=/var/lib/postgresql/data postgres:17-alpine
docker exec dk-pg-backup pg_isready -h 127.0.0.1 -U lesson -d source_dbПовторите pg_isready после завершения старта, пока он не сообщит accepting connections. Адрес 127.0.0.1 проверяет TCP-сервер: временный сервер этапа инициализации образа использует Unix-сокет и ещё не означает завершённый запуск. Используем клиенты внутри того же образа PostgreSQL: это устраняет случайную несовместимость локального pg_dump с сервером. Пример рассчитан на путь данных образа версии 17; у других major проверяйте описание image. Официальный образ PostgreSQL.
Данные с проверяемым результатом
docker exec -i dk-pg-backup psql -v ON_ERROR_STOP=1 -U lesson -d source_db <<'SQL'
CREATE TABLE notes (id integer PRIMARY KEY, body text NOT NULL);
INSERT INTO notes VALUES (1, 'alpha'), (2, 'beta'), (3, 'gamma');
SELECT count(*) AS rows, sum(id) AS id_sum FROM notes;
SQLОжидается 3 строки и сумма 6. ON_ERROR_STOP=1 делает SQL-ошибку видимой вызывающему сценарию. Без проверки кода выхода shell может продолжить выполнение после неудачного шага.
Создадим архив
mkdir -p backup-lab
docker exec dk-pg-backup pg_dump -U lesson -d source_db -Fc > backup-lab/source.dump
test -s backup-lab/source.dump
docker exec -i dk-pg-backup pg_restore --list < backup-lab/source.dumpПеренаправление > выполняет shell хоста: архив сохранён на компьютере, а не только в контейнере. Перед следующей командой убедитесь, что pg_dump завершился с кодом 0; наличие непустого файла само по себе не доказывает успешную копию. Не добавляйте -t к docker exec для бинарного архива: псевдотерминал здесь не нужен.
-Fc создаёт custom format для pg_restore. Plain SQL dump восстанавливают через psql, это другой сценарий. pg_dump снимает логически согласованный снимок одной базы, но не сохраняет роли и все глобальные объекты кластера; также это не механизм point-in-time recovery. Границы pg_dump.
Восстановим в отдельную базу
docker exec dk-pg-backup createdb -U lesson restored_db
docker exec -i dk-pg-backup pg_restore -U lesson -d restored_db --no-owner --no-acl --exit-on-error --single-transaction < backup-lab/source.dump
docker exec dk-pg-backup psql -v ON_ERROR_STOP=1 -U lesson -d restored_db -c 'SELECT count(*) AS rows, sum(id) AS id_sum FROM notes;'
docker exec dk-pg-backup psql -v ON_ERROR_STOP=1 -U lesson -d restored_db -c 'SELECT id, body FROM notes ORDER BY id;'Ожидайте прежние 3/6 и пары alpha, beta, gamma. --single-transaction позволяет откатить неудачное восстановление этой небольшой базы целиком; режим не сочетают с параллельным jobs. --no-owner и --no-acl упрощают учебный перенос, но означают, что владение и права оригинала не воспроизводятся. Параметры pg_restore.
Что проверять помимо count
Одинаковое количество строк ещё не доказывает правильность содержимого. Сравните значения, ключи, ограничения и нужные приложению запросы. В реальном плане восстановления учитывайте расширения, роли, секреты доступа, время восстановления и размер копии. Сохранение архива рядом с единственным рабочим диском не защищает от потери этого диска.
При unsupported version in file header проверьте версию pg_restore. При relation already exists не стирайте исходную базу: вероятно, восстановление направлено в непустую цель. Создайте новую учебную базу с другим именем и повторите только restore после выяснения причины.
Упражнение и уборка
Добавьте четвёртую строку в source_db после dump и убедитесь, что restored_db всё ещё содержит три. Так вы проверите момент снимка. Сохраните результаты restore и SQL-проверок. После занятия остановите и удалите dk-pg-backup, затем удалите только учебный dk-pg-backup-data, если данные больше не нужны; архив останется в backup-lab. Тот же процесс применим к PostgreSQL из [Compose-урока](/lessons/without-university/docker-containerization/docker-developer-23), но сначала нужно явно выбрать нужный сервис и базу.