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

Сколько RAM нужно для Percona XtraBackup

MAATRIX

Percona XtraBackup снимает бэкап InnoDB без блокировки таблиц — база продолжает принимать запросы, пока утилита копирует файлы данных. Проблема в другом: на VPS с 2-4 ГБ RAM бэкап крупной базы иногда падает по OOM или роняет саму СУБД, а нового администратора это застаёт врасплох, потому что XtraBackup вроде бы «не про память», а про диск. На деле память ему нужна — просто расходуется она не там, где ждёшь, и не пропорционально размеру базы. Разберём, что именно ест RAM на этапах backup и prepare, и как посчитать запас заранее.

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

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

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

Почему XtraBackup вообще не похож на mysqldump по памяти

mysqldump строит SQL-дамп через обычные SELECT-запросы — сервер MySQL/MariaDB читает данные через buffer pool, и вся нагрузка на память ложится на сам сервер СУБД. XtraBackup работает иначе: он копирует файлы .ibd и .frm напрямую с диска, в обход buffer pool, а согласованность обеспечивает не блокировкой таблиц, а параллельным чтением redo-лога (InnoDB log files) и применением его к скопированным файлам при --prepare.

Отсюда два следствия, которые стоит держать в голове:

  • Размер innodb_buffer_pool_size вашего боевого сервера не имеет прямого отношения к тому, сколько RAM нужно самому процессу xtrabackup. Buffer pool продолжает работать как обычно, XtraBackup его не трогает.
  • Память XtraBackup расходует на свои внутренние буферы: параллельные потоки копирования, сжатие, поток чтения redo-лога и (отдельная история) применение лога на этапе --prepare. Это принципиально другая модель расхода, чем у логических дампов.

Если вы уже настраивали бэкап MySQL на VPS через mysqldump, будьте готовы, что профиль потребления памяти у XtraBackup выглядит совсем иначе — меньше зависит от размера базы и больше от параметров запуска.

Что реально ест память во время backup-стадии

На стадии снятия бэкапа (xtrabackup --backup --target-dir=...) память расходуется на несколько независимых вещей:

  1. Поток чтения redo-лога. XtraBackup запускает фоновый поток, который читает InnoDB redo log параллельно с копированием файлов данных, чтобы «догнать» изменения, случившиеся во время бэкапа. Буфер под этот поток небольшой (десятки мегабайт), но он обязателен и работает всё время бэкапа.
  2. Параллельные потоки копирования (--parallel=N). Каждый поток копирует свой файл .ibd независимо, используя буферизованное чтение/запись через файловую систему. Чем больше N, тем больше одновременных операций ввода-вывода и тем заметнее расход через страничный кэш ОС (не через RSS процесса напрямую, но свободная память системе всё равно нужна).
  3. Сжатие (--compress, --compress-threads=N). Каждый поток сжатия держит буфер под порцию данных (--compress-chunk-size, по умолчанию около 64 КБ на чанк, но с учётом очередей и буферов zlib/qpress реальный расход на поток ощутимо выше). Сжатие включается отдельно от параллельного копирования — это два независимых множителя памяти.
  4. Шифрование (--encrypt), если используется. Добавляет ещё один слой буферов на поток, аналогично сжатию.
  5. xbstream, если бэкап стримится в один файл (--stream=xbstream) — буферизует поток перед записью или отправкой по сети (например, при бэкапе сразу на другой сервер через ssh или nc).

Важный нюанс: почти все эти буферы масштабируются числом потоков, а не размером базы. База на 10 ГБ и база на 500 ГБ при одинаковых --parallel и --compress-threads потребляют на backup-стадии сопоставимый объём RAM — просто вторая копируется дольше. Это отличает XtraBackup от логических инструментов и от дедуплицирующих бэкаперов вроде BorgBackup, где память растёт от числа чанков и файлов, а не от параметров запуска.

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

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

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

Отдельный зверь: --use-memory на этапе prepare

Если backup-стадия относительно экономна по памяти, то --prepare — совсем другая история, и именно здесь чаще всего случаются сюрпризы.

Команда xtrabackup --prepare --target-dir=/backup --use-memory=1G применяет накопленный redo-лог к скопированным файлам данных, доводя их до консистентного состояния (то же самое, что делает InnoDB crash recovery при старте сервера после сбоя). Параметр --use-memory — это аналог innodb_buffer_pool_size, но только для процесса prepare: чем больше памяти доступно, тем быстрее применяется лог, особенно если во время бэкапа накопилось много транзакций.

По умолчанию --use-memory равен относительно скромному значению (в районе 100 МБ в старых версиях, в свежих сборках Percona XtraBackup 8.x значение может отличаться — проверяйте xtrabackup --help для вашей версии), и на базе с активной записью подготовка бэкапа с дефолтным значением может занимать заметно больше времени, чем с явно увеличенным --use-memory.

Практическое правило, которым пользуются на выделенных бэкап-серверах: если prepare выполняется не на боевом сервере, а на отдельной машине (или отдельном VPS, куда бэкап только заливается для проверки), можно смело отдавать под --use-memory 50-70% доступной RAM — эта память нужна только на время выполнения --prepare и освобождается сразу после завершения:

xtrabackup --prepare \
  --target-dir=/backup/2026-08-30 \
  --use-memory=4G

Если же prepare зачем-то запускается на самом продакшн-сервере (чего лучше избегать — см. ниже), --use-memory нужно выставлять с оглядкой на текущий innodb_buffer_pool_size и запас RAM, а не по остаточному принципу.

Сколько RAM нужно в зависимости от размера базы: ориентиры

Точной формулы «RAM = f(размер_базы)», как для BorgBackup или дедуплицирующих инструментов, у XtraBackup нет — потому что, как описано выше, backup-стадия почти не зависит от объёма данных. Но есть практические ориентиры, собранные из типичных конфигураций на VPS. Это именно ориентиры для прикидки, не официальный бенчмарк Percona — на вашей нагрузке цифры могут отличаться, особенно если сервер параллельно обслуживает боевой трафик:

Размер базыПример параметров backupСвободная RAM желательноRAM под --use-memory при prepare
до 10 ГБ--parallel=2от 1 ГБ сверх buffer pool512 МБ - 1 ГБ
10-50 ГБ--parallel=4 --compress --compress-threads=2от 2 ГБ сверх buffer pool1-2 ГБ
50-200 ГБ--parallel=4-8 --compress --compress-threads=4от 3-4 ГБ сверх buffer pool2-4 ГБ
200 ГБ+--parallel=8+, отдельный бэкап-хост4 ГБ+ сверх buffer pool4-8 ГБ (на отдельной машине)

«Свободная RAM сверх buffer pool» здесь — не память самого процесса xtrabackup (она в разы меньше), а запас, который стоит держать на сервере, чтобы копирование через страничный кэш ОС не начало вытеснять горячие страницы buffer pool и не спровоцировало своп у самого MySQL/MariaDB во время бэкапа. Именно этот эффект, а не аппетит самого xtrabackup, чаще всего кладёт продакшн при бэкапе «в лоб» на маленьком VPS.

Как параметры --parallel и --compress-threads множат друг друга

Частая ошибка — считать, что --parallel=8 и --compress-threads=8 вместе дадут «восьмикратный» расход. На практике это два независимых пула потоков, и их влияние на память примерно перемножается, а не складывается: --parallel определяет, сколько файлов копируется одновременно, --compress-threads — сколько потоков сжимает уже скопированные данные. При --parallel=4 --compress-threads=4 одновременно может выполняться до 4 операций копирования и до 4 операций сжатия — то есть по факту до 8 активных рабочих потоков, каждый со своим буфером.

На VPS с ограниченной RAM разумнее держать оба параметра скромными и наращивать постепенно, глядя на free -h во время тестового прогона, а не выставлять сразу число ядер CPU в оба параметра:

# Осторожный старт на сервере с 2-4 ГБ RAM
xtrabackup --backup \
  --target-dir=/backup/$(date +%F) \
  --parallel=2 \
  --compress \
  --compress-threads=2 \
  --user=backup_user --password=*** 

Если сервер тянет — параметры увеличивают итерационно, а не сразу «на максимум». Если у вас база под MariaDB, схема настройки самого сервера описана отдельно — XtraBackup работает с MariaDB так же, как с MySQL, разница только в отдельных нюансах поддерживаемых версий.

Что произойдёт, если памяти не хватило

Три типичных сценария, если вы недооценили запас RAM:

  • OOM killer убивает процесс xtrabackup. Бэкап обрывается на середине, в целевой директории остаются недописанные файлы. Такой бэкап нельзя «допрепарировать» — его нужно снимать заново. Проверить, было ли это OOM, можно командой dmesg | grep -i "killed process" или journalctl -k | grep -i oom сразу после сбоя.
  • Система уходит в своп. Если на сервере есть swap, вместо явного падения вы получаете резкое замедление — и бэкап, и сам продакшн-сервер СУБД начинают тормозить одновременно, потому что своп конкурирует за диск с теми же файлами, которые копирует XtraBackup. Это часто хуже прямого OOM-килла, потому что деградация проявляется не сразу и не очевидна в логах.
  • --prepare не хватает памяти под --use-memory. Здесь обычно не падение, а просто медленное применение лога — процесс использует меньше памяти, чем задано, если её физически нет, но конкурирует с другими процессами за оставшуюся RAM.

Если сервер потенциально маловат, стоит подстраховаться системным лимитом, чтобы xtrabackup не утащил за собой продакшн-СУБД по OOM score:

systemd-run --scope -p MemoryMax=1500M \
  xtrabackup --backup --target-dir=/backup/$(date +%F) --parallel=2

Так при превышении лимита упадёт только сам бэкап, а не случайный процесс, выбранный ядром по эвристике OOM — часто им оказывается сам mysqld.

Практические рекомендации: чеклист перед первым боевым бэкапом

  • Снимайте prepare на отдельной машине, если размер базы позволяет — это снимает почти весь риск для продакшна: на боевом сервере остаётся только backup-стадия с её скромными и предсказуемыми буферами.
  • Тестируйте на копии данных перед первым боевым запуском — прогоните --backup, затем --prepare на VPS с примерно такой же RAM, что и продакшн, наблюдая free -h в отдельном терминале.
  • Держите запас RAM сверх buffer pool, а не впритык — ориентиры из таблицы выше плюс 20-30% на непредвиденное (второй параллельный процесс, всплеск нагрузки на СУБД во время бэкапа).
  • Не выставляйте --parallel и --compress-threads в число ядер CPU по умолчанию на серверах с малой RAM — на 2-4 ядрах и 2 ГБ RAM это может оказаться агрессивнее, чем нужно; лучше начать с 2 и поднимать.
  • Логируйте dmesg/journalctl вокруг времени запуска бэкапа в мониторинге, чтобы не разбираться постфактум, был ли это OOM.
  • Если бэкапы регулярно упираются в память на текущем тарифе — часто разумнее не резать параллелизм до предела, а взять VPS с бóльшим объёмом RAM: экономия на тарифе обычно обходится дороже времени, потраченного на подбор параметров и разбор упавших бэкапов.

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

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

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

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

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

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

--use-memory — это то же самое, что innodb_buffer_pool_size?

По смыслу да — оба параметра задают объём памяти под кэш страниц InnoDB при применении redo-лога, но --use-memory работает только внутри процесса xtrabackup --prepare и не связан с настройками боевого сервера MySQL/MariaDB.

Можно ли снижать --parallel до 1 на слабом VPS?

Да, --parallel=1 полностью рабочий вариант — бэкап займёт больше времени, но потребление памяти будет минимальным и предсказуемым. Для небольших баз (единицы гигабайт) разница во времени обычно некритична.

Сжатие увеличивает или уменьшает нагрузку на RAM по сравнению с временем на диске?

Сжатие добавляет расход памяти под буферы --compress-threads, но снижает объём операций записи на диск и итоговый размер бэкапа — на VPS с медленным или сетевым диском и ограниченным местом это обычно оправданный компромисс.

Что делать, если prepare нужно выполнить именно на продакшн-сервере?

Ставьте --use-memory с явным запасом ниже свободной RAM (учитывая уже занятый innodb_buffer_pool_size), запускайте в окно минимальной нагрузки и по возможности через systemd-run с лимитом памяти, чтобы исключить конкуренцию с самим mysqld.

Влияет ли --lock-ddl или GTID-режим на потребление памяти?

Нет, это про согласованность и совместимость с репликацией, а не про буферы копирования — на расход RAM эти опции напрямую не влияют.

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

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

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