MAATRIX / Блог / Бэкап и восстановление Meilisearch

Бэкап и восстановление Meilisearch

MAATRIX

Meilisearch хранит весь индекс в одном каталоге data.ms, и первая мысль у многих — просто заархивировать его tar-архивом по крону. На «живом» сервисе это почти гарантированно даёт битую копию: LMDB, на которой построен Meilisearch, пишет данные не атомарно с точки зрения файловой системы, и снятый на живую копию каталог может оказаться неконсистентным именно в момент, когда он понадобится для восстановления. У Meilisearch есть два встроенных механизма, которые решают эту проблему правильно — снапшоты и дампы. Разберём, чем они отличаются, как их настроить по расписанию и, главное, как реально восстановить индекс, а не просто убедиться, что где-то лежит файл с бэкапом.

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

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

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

Снапшоты и дампы — это разные инструменты, а не два способа одного и того же

Путаница чаще всего возникает именно здесь: оба механизма называют «бэкапом», но решают разные задачи.

Снапшот — это бинарная копия базы LMDB, сделанная безопасно, без остановки сервиса. Снапшот быстрый (по сути копирование файлов на уровне движка), сохраняет вообще всё состояние — индексы, задачи, ключи API, настройки — и разворачивается тоже быстро. Ограничение: снапшот жёстко привязан к версии Meilisearch, которой был снят. Восстановить снапшот, снятый на v1.9, в инстанс v1.11 может не получиться — формат внутреннего хранилища между минорными и особенно мажорными версиями иногда меняется несовместимо.

Дамп — это выгрузка данных в переносимый JSON-формат: документы, настройки индексов, задачи. Дамп медленнее снимать и медленнее импортировать (Meilisearch заново индексирует документы при импорте), зато он не привязан к конкретной версии — это официальный путь миграции между версиями и между серверами.

Практическое правило простое: снапшоты — для регулярного, частого бэкапа «как было пять минут назад», дампы — для редких контрольных точек перед обновлением версии или переездом на новый сервер. Хорошая схема резервного копирования использует оба механизма вместе, а не выбирает один вместо другого.

Автоматические снапшоты по расписанию

Снапшоты включаются флагом при запуске Meilisearch — интервал задаётся в секундах, а не через отдельный планировщик:

# /etc/systemd/system/meilisearch.service, секция [Service]
ExecStart=/usr/local/bin/meilisearch \
  --db-path /var/lib/meilisearch/data.ms \
  --http-addr 127.0.0.1:7700 \
  --env production \
  --schedule-snapshot 3600 \
  --snapshot-dir /var/backups/meilisearch/snapshots

--schedule-snapshot 3600 означает снапшот раз в час — подбирайте интервал под то, сколько данных вы готовы потерять при сбое (RPO). Для каталога товаров, который переиндексируется раз в сутки из внешней базы, часового интервала обычно с запасом; для поиска с постоянной живой индексацией (чат, лог событий) может понадобиться каждые 10–15 минут, но учитывайте, что каждый снапшот — это полная копия data.ms, и при большом индексе частые снапшоты быстро съедят место на диске.

После правки юнита:

sudo systemctl daemon-reload
sudo systemctl restart meilisearch
ls -lh /var/backups/meilisearch/snapshots/

Файлы снапшотов называются по времени создания (db.snapshot с таймстампом в имени каталога, в зависимости от версии — сверяйтесь с meilisearch --help для вашей сборки). Meilisearch не удаляет старые снапшоты сам — ротацию нужно настраивать отдельно, иначе диск заполнится:

# /etc/cron.d/meilisearch-snapshot-cleanup — хранить снапшоты за последние 7 дней
0 3 * * * root find /var/backups/meilisearch/snapshots -type f -mtime +7 -delete

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

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

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

Дампы: ручной запуск и что реально в них попадает

Дамп снимается через API, а не флагом запуска, и требует мастер-ключа:

MASTER_KEY=$(sudo cat /etc/meilisearch/master.key)

curl -X POST 'http://127.0.0.1:7700/dumps' \
  -H "Authorization: Bearer $MASTER_KEY"

Ответ приходит сразу, но сам дамп снимается асинхронно — это фоновая задача, и для больших индексов она может занять минуты. Статус проверяется через /tasks:

curl -H "Authorization: Bearer $MASTER_KEY" \
  'http://127.0.0.1:7700/tasks?types=dumpCreation' | python3 -m json.tool

Когда status меняется на succeeded, в поле details.dumpUid будет имя файла — готовый дамп лежит в каталоге, заданном флагом --dump-dir (по умолчанию dumps/ рядом с рабочим каталогом). Скопируйте его в постоянное хранилище бэкапов:

sudo mkdir -p /var/backups/meilisearch/dumps
sudo cp /var/lib/meilisearch/dumps/*.dump /var/backups/meilisearch/dumps/

В дамп попадают документы всех индексов, настройки (searchable/filterable/sortable атрибуты, синонимы, стоп-слова, typo tolerance) и ключи API. Не попадают файл master.key (секрет уровня сервера, храните отдельно) и старые записи очереди задач. Для регулярного снятия дампа по расписанию оберните вызов в скрипт с ожиданием завершения задачи:

#!/bin/bash
set -euo pipefail
MASTER_KEY=$(cat /etc/meilisearch/master.key)
TASK_UID=$(curl -s -X POST 'http://127.0.0.1:7700/dumps' \
  -H "Authorization: Bearer $MASTER_KEY" | python3 -c 'import sys,json;print(json.load(sys.stdin)["taskUid"])')

for i in $(seq 1 60); do
  STATUS=$(curl -s -H "Authorization: Bearer $MASTER_KEY" \
    "http://127.0.0.1:7700/tasks/$TASK_UID" | python3 -c 'import sys,json;print(json.load(sys.stdin)["status"])')
  [ "$STATUS" = "succeeded" ] && break
  [ "$STATUS" = "failed" ] && { echo "dump failed"; exit 1; }
  sleep 10
done

cp /var/lib/meilisearch/dumps/*.dump /var/backups/meilisearch/dumps/dump-$(date +%F).dump
find /var/backups/meilisearch/dumps -name '*.dump' -mtime +14 -delete

Ставьте это в cron раз в сутки — дамп нагружает CPU и диск заметнее снапшота, гонять его чаще обычно не нужно.

Восстановление из снапшота: самый быстрый путь после сбоя

Снапшот восстанавливается флагом --import-snapshot при старте — Meilisearch должен быть остановлен, а каталог с данными пустым или отсутствовать:

sudo systemctl stop meilisearch
sudo rm -rf /var/lib/meilisearch/data.ms
sudo -u meilisearch /usr/local/bin/meilisearch \
  --db-path /var/lib/meilisearch/data.ms \
  --import-snapshot /var/backups/meilisearch/snapshots/2026-08-31T12-00-00.snapshot \
  --http-addr 127.0.0.1:7700 \
  --env production

Так удобно проверить вручную, что снапшот вообще поднимается и отдаёт данные, прежде чем возвращать сервис под systemd. Убедившись, что он стартовал и здоров, остановите ручной процесс (Ctrl+C) и запустите штатно — если добавляли --import-snapshot в ExecStart, уберите флаг после первого успешного запуска, иначе при каждом рестарте сервис будет заново импортировать тот же снапшот поверх существующих данных.

Проверка после восстановления — обязательный шаг, а не формальность:

curl -H "Authorization: Bearer $MASTER_KEY" http://127.0.0.1:7700/health
curl -H "Authorization: Bearer $MASTER_KEY" http://127.0.0.1:7700/indexes | python3 -m json.tool
curl -X POST http://127.0.0.1:7700/indexes/products/search \
  -H "Authorization: Bearer $SEARCH_KEY" \
  --data '{"q": "тест"}'

Сверьте количество документов в каждом индексе (numberOfDocuments в статистике индекса) с тем, что ожидалось на момент снятия снапшота — расхождение подскажет, не потеряли ли вы данные, записанные между снапшотом и сбоем.

Восстановление из дампа и перенос на новый сервер

Дамп восстанавливается похожим флагом, --import-dump, и тоже требует остановленного сервиса с пустым каталогом данных:

sudo systemctl stop meilisearch
sudo rm -rf /var/lib/meilisearch/data.ms
sudo -u meilisearch /usr/local/bin/meilisearch \
  --db-path /var/lib/meilisearch/data.ms \
  --import-dump /var/backups/meilisearch/dumps/dump-2026-08-31.dump \
  --http-addr 127.0.0.1:7700 \
  --env production

Разница с восстановлением снапшота ощутима на практике: Meilisearch не копирует бинарные структуры, а заново прогоняет документы через индексацию — на десятках тысяч записей это секунды, на миллионах может растянуться на минуты и заметно нагрузить CPU. Прогресс виден в логах сервиса или через /tasks сразу после запуска.

Именно дамп — правильный инструмент для переезда на новый сервер, а не копирование каталога data.ms целиком: дамп не зависит от версии Meilisearch и от архитектуры процессора, тогда как сырые файлы LMDB такой гарантии не дают. Порядок переноса:

# на старом сервере
curl -X POST 'http://127.0.0.1:7700/dumps' -H "Authorization: Bearer $MASTER_KEY"
# дождаться succeeded, скопировать *.dump на новый сервер
scp /var/lib/meilisearch/dumps/latest.dump user@new-server:/tmp/

# на новом сервере — установка по общей схеме, затем
sudo systemctl stop meilisearch
sudo -u meilisearch meilisearch --db-path /var/lib/meilisearch/data.ms \
  --import-dump /tmp/latest.dump --http-addr 127.0.0.1:7700 --env production

Если этот шаг для вас первый, сама установка Meilisearch с нуля — systemd-юнит, мастер-ключ, Nginx с SSL — подробно разобрана в статье как установить и настроить Meilisearch на VPS. Ключи API, которые генерировались на старом сервере, в дамп попадают, но помните: сам мастер-ключ сервера — отдельный секрет, задайте его на новом сервере заново (можно тот же, можно новый) и обновите переменную окружения приложений при необходимости.

Хранение бэкапов вне сервера и мониторинг процесса

Снапшоты и дампы, лежащие на том же диске, что и рабочий индекс, защищают от порчи данных, но не от отказа сервера целиком — диск умер, сервер украли, датацентр сгорел. Копию нужно регулярно увозить на физически другую машину.

Для локального каталога /var/backups/meilisearch подходит любой инструмент общего назначения, которым вы уже бэкапите остальные сервисы на сервере — отдельную схему под Meilisearch городить не нужно. Если уже стоит BorgBackup, достаточно добавить путь в список архивируемых каталогов — установка описана в статье про BorgBackup на Ubuntu 24.04; Restic для той же задачи местами удобнее за счёт встроенной поддержки S3-бэкендов, сравнение — в статье Restic или BorgBackup: что выгоднее и когда. Если индекс хранит чувствительные данные (поиск по клиентской базе с email или телефонами), копию стоит шифровать перед отправкой наружу — принципы описаны в статье про бэкап с шифрованием.

Сам процесс бэкапа тоже нужно мониторить — иначе о том, что cron несколько недель падает с ошибкой прав доступа, вы узнаете в момент, когда бэкап понадобится по-настоящему:

#!/bin/bash
set -euo pipefail
# ... снятие дампа ...
curl -fsS -m 10 --retry 3 "https://hc-ping.com/ваш-uuid" >/dev/null || true

Пинг на внешний сервис вроде healthchecks.io после успешного завершения скрипта — минимальный, но рабочий способ заметить проблему до инцидента, а не после.

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

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

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

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

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

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

Можно ли просто скопировать каталог data.ms через rsync или tar на живом сервисе?

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

Что быстрее восстанавливается — снапшот или дамп?

Снапшот, часто в разы: это копирование бинарных файлов, а не повторная индексация документов. Для сценария «сервис упал, нужно поднять как можно быстрее» держите свежий снапшот. Дамп используйте, когда меняете версию Meilisearch или переезжаете на другое железо.

Нужно ли останавливать Meilisearch, чтобы снять снапшот или дамп?

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

Дамп содержит мастер-ключ?

Нет. Мастер-ключ — секрет уровня процесса, задаётся переменной окружения MEILI_MASTER_KEY и в дамп не попадает. При восстановлении на новом сервере ключ нужно задать заново; ключи API (search-key, indexing-key), которые вы создавали через /keys, в дамп входят.

Как проверить, что бэкап реально рабочий, не дожидаясь сбоя?

Разверните тестовый инстанс Meilisearch на отдельном порту или временном сервере, импортируйте туда последний снапшот или дамп и выполните пару поисковых запросов, сверив количество документов со статистикой индекса на проде. Это стоит делать не реже раза в месяц — идея та же, что и для любых других бэкапов баз данных, разобранная в статье про восстановление из бэкапа на практике.

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

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

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