Восстановление дампа PostgreSQL: запускаем и мониторим, что процесс идёт

Разворачивание большого SQL-дампа через psql может занять часы. В какой-то момент почти у каждого возникает вопрос: «Оно ещё работает или уже зависло?». В этой статье — команда запуска импорта и набор запросов, которые позволяют мониторить процесс.

Команда запуска импорта

Базовый вариант для дампа, созданного с флагами --inserts --column-inserts:

Разберём ключи:

ФлагЗачем
-h localhost -U username -p 5433Параметры подключения (те же, что при pg_dump)
-d databaseЦелевая БД. Должна существовать заранее
-f dump.sqlФайл с дампом
-qТихий режим: не засорять консоль строками INSERT 0 1
-v ON_ERROR_STOP=1Прервать при первой ошибке, а не «дожевать» до конца

Хотите сохранить лог на будущее, но не засорять консоль:

Консоль чистая, весь вывод — в restore.log.

Диагностика: работает или висит?

Пока импорт идёт, откройте вторую сессию psql (к той же или любой другой БД) и выполните диагностический запрос.

Что делает сервер прямо сейчас

Запросим текущую активность сервера по интересующей нас базе данных:

Что означают поля:

state — состояние сессии:

ЗначениеЧто означает
activeЗапрос выполняется. Скорее всего, просто долго
idle in transactionТранзакция открыта, но ничего не делает. Возможно, psql чего-то ждёт
idleСессия простаивает. Может быть, клиент уже отвалился

wait_event_type / wait_event — на чём именно процесс ждёт:

ЗначениеЧто означает
NULLПроцесс работает, не ждёт. Не завис
LockЖдёт блокировку. Кто-то держит таблицу — самая частая причина «зависания»
IO (DataFileRead, WALWrite и др.)Ждёт диск. Работает, просто медленно
ClientЖдёт данных от клиента. Странно, если вы ничего не вводите
Timeout, LWLock, BufferPinВнутренние ожидания, обычно нормальны

duration — сколько уже длится запрос. Если значение растёт — процесс жив.

Кто кого блокирует

Если в поле wait_event_type стоит Lock — надо найти виновника:

В колонке blocking_query будет тот запрос, который держит вашу таблицу. Часто это забытая транзакция (idle in transaction) или другое приложение, забывшее сделать COMMIT.

Быстрый способ посмотреть все неудовлетворённые блокировки:

Растёт ли прогресс

Для начала подключитесь к нужной базе (консоль psql):

Самый надёжный признак, что работа идёт — меняются счётчики. Несколько независимых способов:

Размер базы данных. Повторите запрос дважды с паузой 20–30 секунд:

Database — это имя вашей базы данных.

Если размер растёт — данные заливаются.

Статистика вставок:

  • n_live_tup — оценка числа «живых» строк во всех пользовательских таблицах. Растёт по мере заливки данных, но это оценка планировщика, а не точный count(*). Обновляется фоновым процессом статистики (autovacuum/stats collector), поэтому может «отставать» на секунды.
  • n_tup_ins — сколько строк вставлено с момента сброса статистики. Это накопительный счётчик, он только растёт и никогда не уменьшается, пока статистику не сбросят.

Именно n_tup_ins — самый полезный для отслеживания прогресса: он монотонно увеличивается, пока идут INSERT-ы.

Статистика собирается асинхронно, с интервалом в несколько секунд. Для мониторинга это нормально, но не ждите мгновенной реакции.

Прямой count(*) по таблице, если знаете, куда льются данные:

Алгоритм такой — посмотрели что делает сервер прямо сейчас (увидели что идет команда INSERT в какую то таблицу), а потом можно выполнить пару раз count(*) по этой таблице, чтобы убедиться, что число строк растет.

Типичные причины «зависания»

Сетевые проблемы. Если сервер не локальный, большие потери пакетов и высокий RTT сильно тормозят поштучные INSERT-ы.

Блокировка (lock). Кто-то другой держит таблицу. Самая частая причина. Лечится поиском и завершением блокирующего.

idle in transaction у самого restore-процесса. Дамп открыл транзакцию (BEGIN) и ждёт чего-то, что не приходит.

Медленный формат дампа. --inserts --column-insertsсамый медленный формат восстановления: каждая строка — отдельный INSERT, часто отдельная транзакция, round-trip к серверу на каждую строку.

Нехватка ресурсов. Диск в 100%, CPU на пределе, мало RAM — всё замедляется.

Как ускорить восстановление в будущем

Формат --inserts --column-inserts выбирают, когда важна переносимость дампа (например, для загрузки в другую СУБД). Для обычного бэкапа PostgreSQL он не оптимален. Альтернативы:

  • COPY (по умолчанию). pg_dump без --inserts использует COPY FROM stdin — в разы быстрее, чем построчные INSERT.
  • Custom-формат -Fc + pg_restore -j 4. Позволяет параллельное восстановление и выборочную загрузку отдельных таблиц.
  • Обернуть restore в одну транзакцию. Добавьте BEGIN; в начало дампа и COMMIT; в конец — коммитов будет один, а не миллион.

Мало букафф? Читайте есчо !

Приоритет настроек в PostgreSQL

Сентябрь 17, 2026 г.

Есть чёткая иерархия, как PostgreSQL читает свои настройки. Порядок чтения конфигурации PostgreSQL при старте (и при reload) собирает итоговую ...

Читать

Ошибка: cлишком много клиентов psql

Сентябрь 17, 2026 г.

В php пример этой выглядит как следующее сообщение:PDOException: SQLSTATE[08006] [7] connection to server at "127.0.0.1", port 5433 failed: извините, уже ...

Читать

Перенос базы PostgreSQL с сервера на сервер

Январь 24, 2017 г.

Не простая операция,  если вы не имели опыта настройки / работы с postgresql до сих пор. Расскажу поэтапно как выгрузить дамп базы, и как затем этот дамп ...

Читать

Шпаргалка: извлечь текст из поля bytea (binary) в PostgreSQL

Май 6, 2026 г.

Cитуация: поле в таблице имеет тип bytea (бинарные данные), но вы точно знаете, что внутри него хранится обычный текст (например, из-за ошибки проектирования или legacy-системы). НЕ используйте ::text — он покажет шестнадцатеричный код (\x48656C6C6F), ...

Читать
 

Комментарии к «Восстановление дампа PostgreSQL: запускаем и мониторим, что процесс идёт»

Понравилась статья? Есть вопросы? - пишите в комментариях.



Комментарий: