Эксплуатация: бэкапы, валидация схемы, Atlas

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

Эксплуатация (operations) — всё, что держит базу живой и безопасной в проде: резервное копирование, валидация данных, мониторинг, разграничение доступа и, как удобный вариант, управляемое облако MongoDB Atlas.

Бэкапы: mongodump и mongorestore

Простейший способ снять резервную копию — логический дамп. mongodump выгружает данные в формате BSON, а mongorestore заливает их обратно:

// снять дамп всей базы (по желанию — сжать)
mongodump --uri="mongodb://localhost:27017/shop" --out=/backup --gzip

// восстановить (--drop предварительно очистит коллекции)
mongorestore --uri="mongodb://localhost:27017/shop" --drop --gzip /backup/shop

// можно одним архивом вместо каталога
mongodump --uri="mongodb://localhost:27017" --archive=dump.gz --gzip

Это удобно для небольших и средних баз, переноса данных между окружениями и быстрых снимков. Но у mongodump есть пределы: на больших боевых базах восстановление идёт медленно (данные перезаливаются и переиндексируются), а сам по себе дамп не даёт point-in-time recovery (восстановления на конкретный момент). Для серьёзного прода используют снапшоты тома или непрерывные бэкапы (в Atlas — встроенные). Запомните правило: бэкап без проверенного восстановления — это не бэкап; регулярно прогоняйте тестовый restore.

Валидация схемы: $jsonSchema

MongoDB гибкая — документы в коллекции могут отличаться по форме. Это плюс на старте, но в проде хочется гарантий: «у заказа всегда есть сумма и она число». Для этого к коллекции прикрепляют валидатор на основе $jsonSchema:

{
  "$jsonSchema": {
    "bsonType": "object",
    "required": ["customerId", "total", "status"],
    "properties": {
      "customerId": { "bsonType": "objectId" },
      "total":      { "bsonType": "decimal", "minimum": 0 },
      "status":     { "enum": ["new", "paid", "shipped"] }
    }
  }
}
// прикрепить валидатор при создании коллекции
db.createCollection("orders", { validator: { /* схема выше */ } })

// или к существующей коллекции через collMod
db.runCommand({
  collMod: "orders",
  validator: { /* схема */ },
  validationLevel: "moderate",   // strict | moderate
  validationAction: "warn"       // error | warn
})

Два важных рычага. validationAction: error (по умолчанию) отклоняет невалидные документы, warn только пишет предупреждение в лог. validationLevel: strict проверяет все вставки и обновления, moderate не трогает уже существующие невалидные документы при их обновлении. Это спасает при постепенной миграции легаси-данных.

Мониторинг

Чтобы понимать, что происходит с кластером, MongoDB даёт встроенные команды и утилиты:

ИнструментЧто показывает
db.serverStatus()сводка: соединения, операции, память, репликация
db.currentOp()выполняемые прямо сейчас операции (найти «зависшие»)
mongostat / mongotopживые метрики нагрузки и времени по коллекциям
профайлерлог медленных запросов (db.setProfilingLevel(1, 100))

Профайлер с порогом (например, логировать всё медленнее 100 мс) — лучший способ найти проблемные запросы, а затем разобрать их через explain() и закрыть индексом. В Atlas всё это есть из коробки: графики, алерты и Performance Advisor, который сам предлагает индексы по реальной нагрузке.

MongoDB Atlas — облако

Atlas — управляемый сервис MongoDB (DBaaS) от самой MongoDB Inc., работающий в AWS, GCP и Azure. Он берёт на себя рутину: разворачивает replica set, делает автоматические бэкапы, масштабирует кластер, мониторит, накатывает обновления и сразу включает безопасность. Есть бесплатный тариф M0 — удобно для учёбы и пет-проектов. Подключение идёт по SRV-строке, где драйвер сам узнаёт топологию через DNS:

mongodb+srv://app_user:[email protected]/shop?retryWrites=true&w=majority

В Atlas доступ к кластеру по умолчанию закрыт: нужно явно добавить IP-адреса в network access list (или настроить VPC peering) и создать пользователей с ролями. Это снимает с команды задачи по эксплуатации и заодно защищает от типичных ошибок конфигурации.

Как это работает под капотом

Валидатор хранится в опциях коллекции и проверяется движком на каждой записи в зависимости от validationLevel. Профайлер пишет записи в служебную capped-коллекцию system.profile, поэтому он не растёт бесконечно. Atlas под капотом запускает обычные replica set/шардированные кластеры, а оркестрацией (выкатка узлов, ротация, бэкапы) занимается фоновый агент автоматизации — то есть «магии» нет, это тот же MongoDB, только обслуживаемый за вас.

Базовая безопасность: аутентификация и роли

MongoDB поддерживает аутентификацию и ролевую модель доступа (RBAC). В проде аутентификация обязана быть включена (--auth; в Atlas — всегда). Пользователю выдают встроенные роли по принципу наименьших привилегий:

// пользователь только для приложения: чтение+запись в одной базе
db.createUser({
  user: "app_user",
  pwd: passwordPrompt(),
  roles: [ { role: "readWrite", db: "shop" } ]
})

// аналитик — только чтение
db.createUser({
  user: "analyst",
  pwd: passwordPrompt(),
  roles: [ { role: "read", db: "shop" } ]
})

Минимальный набор правил безопасности: включить аутентификацию; давать узкие роли (read, readWrite на конкретную базу, а не root на всё); шифровать трафик через TLS; не выставлять mongod в публичный интернет без файрвола. Последний пункт — не формальность: открытые в интернет базы MongoDB без пароля массово находили и шифровали ради выкупа. Закрытый сетевой доступ + аутентификация — обязательный минимум.

Частые ошибки

  • Считать mongodump единственным бэкапом большой боевой базы. На больших объёмах восстановление мучительно долгое и нет point-in-time. Дополняйте снапшотами/непрерывными бэкапами и тестируйте restore.
  • Включить строгую валидацию на коллекцию с легаси-данными. validationAction: "error" начнёт отклонять обновления старых невалидных документов. На миграции используйте moderate и warn.
  • Выставить базу в интернет без аутентификации. Классическая причина утечек и ransomware. Включайте --auth и закрывайте доступ сетью.
  • Раздавать роль root всем подряд. Приложению нужен readWrite на свою базу, а не суперправа на весь кластер. Минимум привилегий.
  • Не мониторить. Без профайлера и метрик проблемы всплывают только когда «всё лежит». Настройте алерты заранее.

Итоги

  • mongodump/mongorestore — простой логический бэкап; для большого прода дополняйте снапшотами и проверяйте восстановление.
  • $jsonSchema-валидатор задаёт форму документов; validationLevel и validationAction позволяют мягко мигрировать.
  • Мониторинг — serverStatus, currentOp, профайлер медленных запросов; в Atlas есть метрики, алерты и Performance Advisor.
  • Atlas — управляемая MongoDB в облаке: репликация, бэкапы, масштабирование и безопасность из коробки, подключение по mongodb+srv://.
  • Базовая безопасность: включённая аутентификация, узкие роли (RBAC, least privilege), TLS и закрытый сетевой доступ — обязательный минимум.
Проверьте себя
1. В чём главное ограничение mongodump как стратегии бэкапа для большой боевой базы?
AОн не умеет сжимать данные
BВосстановление медленное и сам по себе он не даёт point-in-time recovery
CОн работает только в Atlas
DОн удаляет исходные данные после дампа
2. Зачем нужен validationAction со значением "warn" вместо "error" при добавлении $jsonSchema к существующей коллекции?
AЧтобы ускорить запись
BЧтобы не отклонять документы, а лишь логировать нарушения — удобно при постепенной миграции легаси-данных
CЧтобы включить шардирование
DЧтобы зашифровать данные
3. Какой принцип лежит в основе безопасной выдачи ролей пользователям MongoDB?
AВсем выдавать root, чтобы ничего не сломалось
BПринцип наименьших привилегий: давать минимально необходимые роли (например, readWrite на одну базу)
CОтключить аутентификацию для удобства
DОткрыть базу в интернет для доступности