MAATRIX / Блог / Сколько RAM нужно для pgBackRest

Сколько RAM нужно для pgBackRest

MAATRIX

pgBackRest — промышленный стандарт бэкапа PostgreSQL: инкрементальные копии, параллелизм на уровне процессов, поддержка S3-совместимых репозиториев. Но когда приходит время выбрать VPS под бэкап-хост, документация не даёт прямого ответа «сколько RAM». В отличие от restic или BorgBackup, у pgBackRest нет глобального дедуп-индекса и нет официальной формулы расчёта памяти. Разберём, из чего складывается расход RAM, что его двигает и как не промахнуться с тарифом сервера.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Короткий ответ: сколько RAM нужно для pgBackRest

Ориентиры ниже — отправная точка для выбора тарифа, а не гарантия. Точная цифра зависит от числа файлов в PGDATA и от process-max, который вы выставите.

СценарийОсобенностиRAM с запасом
Одна небольшая база, десятки тысяч файлов в PGDATAprocess-max=1, дефолтная компрессия512 МБ – 1 ГБ
База среднего размера, сотни тысяч файлов (партиции, много таблиц)process-max=2-4, дельта-бэкапы1-2 ГБ
Крупная мультитенантная база, много схем и партицийprocess-max=4-8, манифест уже заметен по размеру2-4 ГБ
Репозиторий-хаб для нескольких кластеров PostgreSQLБэкапы нескольких баз идут параллельно, память складывается4-8 ГБ и выше
Репозиторий на S3/GCS с высоким process-maxКаждый воркер держит ещё и буфер клиента объектного хранилища+20-30% к базовому расчёту

Главное отличие от restic и BorgBackup: у pgBackRest память не растёт с ростом дедуп-индекса, потому что дедупликации как таковой нет. Вместо этого есть два независимых рычага — параллелизм (process-max) и манифест бэкапа. Разберём оба.

Почему pgBackRest считается иначе, чем restic и Borg

У restic и BorgBackup главный потребитель памяти — глобальный индекс репозитория: таблица «хеш блока → где он лежит», которая растёт с числом уникальных чанков во всём репозитории и обязана целиком помещаться в RAM при prune и check. У pgBackRest такой структуры нет: нет контент-зависимой дедупликации на уровне блоков, инструмент работает на уровне файлов PostgreSQL и решает, что копировать, через checksum-дельту и page-level incremental backup (с версии 2.46, если включён block-incr), а не через карту блобов.

Это меняет природу расхода RAM:

  • Нет операции, аналогичной prune. Устаревшие бэкапы и WAL удаляются командой expire по политике хранения (repo1-retention-full, repo1-retention-diff) — это не требует карты использования блоков по всей истории, только чтение манифестов конкретных бэкапов под удаление.
  • Память растёт с параллелизмом, а не с историей. pgBackRest написан на C и активно форкает дочерние процессы под process-max. Каждый воркер — отдельный OS-процесс со своими буферами, и именно это, а не глубина истории снапшотов, определяет пиковую память.
  • Манифест — единственная структура, которая масштабируется с базой. Он живёт в памяти на время операции и хранит метаданные (путь, размер, время модификации, checksum) для каждого файла PGDATA, но это плоский список, а не хеш-индекс блоков — расход на файл предсказуемо мал, просто файлов может быть очень много.

Формулы вида «байт на файл» pgBackRest, в отличие от Borg, не публикует — цифры ниже не документированная константа, а инженерная прикидка на основе архитектуры, и её стоит проверять собственным замером.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Манифест: где расход действительно зависит от базы

Манифест бэкапа — это список всех файлов PGDATA (табличные файлы, индексы, pg_wal, конфиги) с их метаданными и контрольными суммами. Он строится при каждом бэкапе, хранится как backup.manifest в каталоге репозитория и параллельно держится в памяти процесса на время операции. Посмотреть его размер на диске можно напрямую:

ls -la /var/lib/pgbackrest/backup/main/*/backup.manifest

В памяти он занимает больше, чем на диске (текстовый формат распакован в структуры), но порядок величины тот же. Ключевой момент — манифест растёт не с объёмом данных в гигабайтах, а с количеством файлов в PGDATA. У PostgreSQL это зависит от числа таблиц, индексов и партиций: одна таблица создаёт минимум один файл (плюс отдельные для TOAST и индексов, а при превышении 1 ГБ — ещё и сегменты). Посчитать реальное число файлов своей базы просто:

find /var/lib/postgresql/16/main -type f | wc -l

База в 500 ГБ с десятком крупных таблиц и база в 500 ГБ с 50 000 партиций мультитенантной схемы дадут разный расход памяти на манифест при одинаковом объёме данных — та же логика, что у restic с индексом блобов, просто единица счёта другая: не чанки, а файлы PGDATA.

Дельта-бэкап (--type=diff или --type=incr) добавляет к этому расходу ещё один манифест — предыдущего бэкапа, с которым идёт сравнение. На практике это удваивает, но не умножает кратно память под манифесты — оба списка одного порядка величины.

process-max и буферы: главный рычаг памяти

Если манифест — фактор, зависящий от базы, то process-max — фактор, который вы контролируете напрямую. По умолчанию pgBackRest использует один процесс (process-max=1), но параллелизм — основной инструмент ускорения бэкапа и восстановления на многоядерном сервере:

[global]
process-max=4
buffer-size=1MiB
compress-type=zst
compress-level=3

Каждый дополнительный воркер — отдельный OS-процесс со своими буферами чтения, сжатия и передачи в репозиторий, размер которых задаёт buffer-size (по умолчанию около 1 МиБ, настраивается от нескольких КиБ до нескольких МиБ). Грубая прикидка суммарной памяти на буферы:

RAM под буферы ≈ process-max × buffer-size × 2-3

Множитель 2-3 — это буфер чтения исходного файла, буфер после сжатия и, для сетевого репозитория, ещё буфер передачи. Базовый оверхед самого процесса на C-бинарнике небольшой, поэтому при умеренном buffer-size рост памяти с process-max почти линейный — в отличие от манифеста, тут не нужно гадать по файлам, значение видно прямо в конфиге.

Практическое следствие: на сервере с 1-2 vCPU задирать process-max выше числа ядер бессмысленно — не даёт ускорения и без причины растит пиковую RAM. Для маленького VPS process-max=1-2 и buffer-size по умолчанию — разумный выбор, параллелизм имеет смысл включать вместе с апгрейдом CPU.

WAL-архивирование: отдельная память, не зависящая от размера базы

Архивирование WAL (archive-push) работает иначе, чем backup: потребление памяти здесь не связано ни с объёмом базы, ни с числом файлов в PGDATA — только с параллелизмом и размером WAL-сегмента (по умолчанию 16 МБ в vanilla PostgreSQL, настраивается только при initdb).

Синхронный режим — PostgreSQL сам вызывает archive_command на каждый закрытый сегмент, это короткоживущий процесс pgbackrest archive-push, который копирует и сжимает один сегмент и завершается. Память здесь минимальна и практически не влияет на выбор тарифа.

Асинхронный режим (archive-async=y) полезен при высокой скорости генерации WAL — команда PostgreSQL завершается сразу после копирования сегмента в локальный spool, а сама передача в репозиторий идёт фоновыми воркерами с собственным process-max:

[global]
archive-async=y
spool-path=/var/spool/pgbackrest

[global:archive-push]
process-max=2

Обратите внимание: process-max можно задавать отдельно для секций archive-push, archive-get, backup и restore в pgbackrest.conf — это позволяет держать архивирование WAL лёгким (1-2 воркера), а сам backup — более параллельным, не завышая общий пик памяти сервера искусственно.

Как посчитать нужный объём и проверить на практике

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

Пиковая память во время реального бэкапа — суммируйте RSS всех процессов pgbackrest, поскольку /usr/bin/time покажет только память родительского процесса, а не форкнутых воркеров:

watch -n1 'ps -o rss,cmd -C pgbackrest | awk "{sum+=\$1} END {print sum/1024\" MB\"}"'

Через cgroup, если pgBackRest запускается как systemd-юнит:

cat /sys/fs/cgroup/system.slice/pgbackrest-backup.service/memory.peak

После сбоя проверьте dmesg -T | grep -i "killed process". Если процесс убит именно в фазе построения или сравнения манифеста, а не во время передачи данных — это признак слишком большого числа файлов в PGDATA при недостаточной RAM, увеличивайте память сервера, а не process-max.

Правило по итогу замера: пик реального бэкапа за пару недель наблюдений плюс 30-40% запаса на рост базы — и это разумная цифра тарифа.

Как снизить расход памяти без апгрейда тарифа

Если сервер уже занят под саму базу и апгрейд под бэкап-хост пока не вариант:

  • Понизьте process-max. Самый прямой рычаг — меньше параллельных воркеров, меньше пиковая память, дольше время бэкапа. На слабом VPS это честный компромисс.
  • Не завышайте buffer-size без нужды. Больший буфер ускоряет передачу на быстрых каналах, но линейно увеличивает память каждого воркера — на канале с ограниченной пропускной способностью выигрыша не будет.
  • Разводите archive-push и backup по разным секциям process-max. Держите архивирование WAL лёгким (1-2 процесса), параллелизм включайте только там, где он реально ускоряет backup.
  • Не запускайте backup и тяжёлый archive-async push одновременно с высоким process-max у обоих. Пики памяти складываются — разнесите по времени.
  • compress-type=zst с умеренным уровнем (2-3) вместо максимального — более высокие уровни zstd используют больше памяти под окно сжатия при небольшом выигрыше в размере.
  • Своп как страховка, не как основной ресурс — спасёт разовый пик при бэкапе базы с неожиданно выросшим числом партиций, но не заменит RAM для регулярной операции:
sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile
sudo mkswap /swapfile && sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Общие подходы к тюнингу самого PostgreSQL, которые снижают нагрузку и на бэкап заодно, разобраны в статье про тюнинг PostgreSQL на VPS.

Какой сервер взять в MAATRIX под pgBackRest

Честный минимум: 1 vCPU, 1 ГБ RAM, диск с запасом ×1,5-2 от объёма репозитория. Подходит для одной небольшой базы без экзотического числа таблиц: process-max=1, дефолтные буферы, полный бэкап раз в сутки без параллелизма.

Рабочий вариант: 2 vCPU, 2 ГБ RAM. Комфортный запас под process-max=2-4, дельта-бэкапы по расписанию, база среднего размера с разумным числом партиций — конфигурация, которую мы советуем чаще всего для отдельного бэкап-хоста PostgreSQL.

Для мультитенантных баз и репозитория-хаба: 4 vCPU, 4-8 ГБ RAM, NVMe или S3-совместимое хранилище отдельно. Здесь стоит сначала посчитать число файлов в PGDATA каждой базы и заложить запас именно под манифест, а не только под параллелизм.

Если хост держит и саму PostgreSQL, и pgBackRest — считайте память отдельно для shared_buffers/work_mem СУБД и отдельно для pgBackRest, они не делят один пул. Установка PostgreSQL на VPS разобрана в статье как установить и настроить PostgreSQL, а восстановление — в материале восстановление базы данных из бэкапа на практике.

Готовый сервер под pgBackRest разворачиваем на MAATRIX за несколько минут, конфигурацию подбираем под число таблиц в вашей базе и желаемый process-max. Оплата — картами российских банков, по СБП, криптовалютой или токеном MAAT, без иностранной карты даже для площадок в Лондоне и США.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Есть ли у pgBackRest официальная формула расчёта RAM, как у BorgBackup?

Нет. Borg публикует оценку chunk_count × 164 + file_count × 240, у pgBackRest такой формулы не задокументировано — архитектура другая, ориентируйтесь на число файлов PGDATA и process-max, а точную цифру проверяйте замером.

Что сильнее влияет на память: размер базы в гигабайтах или число таблиц?

Число файлов в PGDATA, то есть косвенно — число таблиц, индексов и партиций. Две базы по 500 ГБ с разным числом партиций дадут разную нагрузку на манифест при одинаковом объёме данных.

Нужно ли больше RAM для дифференциального бэкапа, чем для полного?

Немного больше — дельта-бэкап держит в памяти два манифеста (текущий и предыдущего для сравнения) вместо одного, но это не кратный рост.

Влияет ли тип репозитория (локальный диск или S3) на память?

Да, через буферы каждого воркера — у S3-совместимого репозитория добавляются буферы клиента объектного хранилища, закладывайте на них 20-30% сверх базового расчёта при высоком process-max.

Что делать, если backup падает по памяти на этапе построения манифеста?

Это признак большого числа файлов в PGDATA при недостаточной RAM, а не проблема параллелизма — снижение process-max почти не поможет, нужна либо память с запасом, либо пересмотр схемы.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →