Перевод и адаптация статьи Grigory Pshekovich «Top 5 Ways to Speed Up pg_dump on Large PostgreSQL Databases» (5 декабря 2025). Авторские права на оригинал принадлежат автору; здесь — пересказ для русскоязычных читателей.
Когда PostgreSQL-база переваливает за несколько гигабайт, pg_dump из быстрой операции превращается в многочасовое мучение, отжирающее ресурсы сервера и срывающее maintenance-окна. Медленные бэкапы — это не только неудобство: растёт риск получить неполный дамп, увеличивается RPO-разрыв и страдает производительность прода в пиковые часы.
Ниже — пять проверенных техник, которые в комбинации могут сократить время pg_dump с часов до минут.
1. Параллельный дамп с directory-форматом
Самая мощная оптимизация — включить параллелизм. По умолчанию pg_dump работает в один поток и дампит таблицы по очереди. С форматом directory (-F d) и флагом -j дамп нескольких таблиц идёт одновременно в разных процессах, и общее время бэкапа уменьшается почти линейно.
| Воркеров | Типичный прирост | Когда подходит |
|---|---|---|
| 2 | ×1.8 | Маленькие серверы, shared hosting |
| 4 | ×3.2 | Стандартные prod-серверы |
| 8 | ×5–6 | Выделенные DB-серверы |
| 16+ | ×7–10 | Высокопроизводительная инфра |
# Параллельный дамп, 4 воркера
pg_dump -F d -j 4 -d myapp -f /backup/myapp_dir/
# Параллельный дамп со сжатием
pg_dump -F d -j 8 -Z 6 -d myapp -f /backup/myapp_dir/Берите количество воркеров примерно равное числу ядер минус 1–2 — оставьте PostgreSQL воздуха. Например, на 16-ядерном сервере хорошо работают -j 12 или -j 14.
2. Исключайте большие, но некритичные таблицы
В большинстве production-баз есть таблицы, которые не обязательно включать в каждый бэкап: audit-логи, session-данные, аналитические события, временные ETL-таблицы. Они нередко занимают 50–80% от всего объёма, при этом данные в них либо восстановимы из других источников, либо вообще не нужны при DR.
Флаг -T (--exclude-table) выкидывает их из дампа:
# Исключаем логи и аналитику
pg_dump -d myapp -T audit_logs -T event_tracking -T sessions -f backup.dump
# Исключаем по шаблону
pg_dump -d myapp -T '*_logs' -T '*_archive' -T 'temp_*' -f backup.dumpПеред тем как выкидывать — пройдитесь по базе и составьте список кандидатов:
- Таблицы с миллионами строк, которые растут ежедневно (логи, метрики, события).
- Исторические архив-таблицы, для которых уже есть отдельная процедура бэкапа.
- Временные / staging-таблицы для ETL.
- Сессионные и кэш-таблицы — они и так временные.
Исключение даже одной большой таблицы может сократить время бэкапа вдвое, при этом критичные для восстановления данные останутся защищёнными.
3. Снижайте уровень сжатия, если важна скорость
Сжатие — это всегда компромисс между размером файла и нагрузкой на CPU. Дефолтный уровень -Z 6 даёт хороший баланс, но для больших баз, где скорость бэкапа важнее размера, снижение уровня даёт ощутимый выигрыш по времени — особенно если место на диске не лимит.
| Уровень | Скорость | Размер файла | Когда применять |
|---|---|---|---|
-Z 0 | Максимум | В 3–5 раз больше | SSD, скорость критична |
-Z 1 | Очень быстро | В 2–3 раза больше | Быстрые ежедневные бэкапы |
-Z 3 | Быстро | В 1.5–2 раза больше | Сбалансированный частый бэкап |
-Z 6 | Средне | Базовый | По умолчанию, подходит большинству |
-Z 9 | Самое медленное | На 10–20% меньше | Архивы, дорогое хранилище |
# Минимальное сжатие — максимум скорости
pg_dump -F c -Z 1 -d myapp -f backup.dump
# Без сжатия — когда диск дешёвый
pg_dump -F c -Z 0 -d myapp -f backup.dumpДля баз больше 100 ГБ переход с -Z 6 на -Z 1 может сократить время бэкапа на 30–40% при увеличении файла всего на 50–70%. Если бэкапы лежат на быстром SSD или места хватает — для ежедневных дампов это часто оправдано.
4. Делайте бэкап в часы низкой активности
Даже со всеми техническими оптимизациями производительность pg_dump сильно зависит от активности самой базы. В пиковые часы дамп конкурирует с продакшн-запросами за I/O, память и CPU. Перенос бэкапа в low-activity окно может сократить время на 20–50% без единой правки в флагах.
Чтобы найти своё «окно тишины», смотрите на:
- активность запросов в
pg_stat_activity; - количество подключений в течение суток;
- метрики I/O из системы мониторинга.
# Cron: бэкап в 03:00 — типичное окно низкой активности
0 3 * * * pg_dump -F c -j 4 -d myapp -f /backup/myapp_$(date +\%Y\%m\%d).dumpПомимо самого расписания, на бэкап-окно стоит:
- временно поднять
maintenance_work_memдля сессии дампа; - проверить
checkpoint_completion_target— он должен размазывать I/O плавно; - поставить на паузу некритичные фоновые джобы и обслуживание.
Связка off-peak + меньше системной конкуренции часто даёт больший прирост, чем любая одна правка флагов.
5. Используйте custom-формат вместо plain SQL
Plain SQL (-F p) генерирует человекочитаемый вывод, но для больших баз он значительно медленнее бинарных форматов. Custom-формат (-F c) — это внутреннее бинарное представление PostgreSQL: пишется быстрее, поддерживает встроенное сжатие и позволяет потом делать параллельный restore.
# Медленно: plain SQL
pg_dump -F p -d myapp -f backup.sql
# Быстро: custom со сжатием
pg_dump -F c -d myapp -f backup.dump
# Самое быстрое: directory + параллельные воркеры
pg_dump -F d -j 4 -d myapp -f /backup/myapp_dir/Бэкапы в custom-формате ещё и гибче при восстановлении — можно выборочно восстановить отдельные таблицы, переупорядочить операции, использовать pg_restore -j для параллельного rеstore. Для баз больше 10 ГБ всегда выбирайте -F c или -F d вместо -F p.
Итог
Ускорение pg_dump на больших базах сводится к пяти стратегиям:
- Параллельный дамп с directory-форматом и
-j N. - Исключение больших некритичных таблиц через
-T. - Снижение уровня сжатия, когда скорость важнее размера.
- Расписание под окно низкой активности.
- Бинарные форматы (custom / directory) вместо plain SQL.
Скомбинировать всё это можно одной командой:
pg_dump -F d -j 8 -Z 1 -T '*_logs' -d myapp -f /backup/dir/Такая связка реально превращает многочасовой бэкап в десятки минут — что, в свою очередь, даёт меньший RPO, меньшую нагрузку на сервер и более надёжную защиту данных.