Как настроить запланированное резервное копирование MongoDB в DigitalOcean Spaces

Вступление

Регулярное резервное копирование базы данных является важным шагом в защите от непреднамеренных событий потери данных. В целом, существует две широкие категории резервных копий: резервные копии на уровне файловой системы («физические») и логические резервные копии.

Резервное копирование на уровне файловой системы включает моментальный снимок базовых файлов данных на определенный момент времени и позволяет базе данных полностью восстановиться, используя состояние, записанное в моментальных снимках файлов. Они играют важную роль в быстром резервном копировании больших баз данных, особенно при использовании в тандеме со снимками файловой системы, такими какLVM snapshots, или снимками блочного тома хранения, такими какDigitalOcean Block Storage Snapshots.

Логические резервные копии включают использование инструмента (например, mongodump илиpg_dump) для экспорта данных из базы данных в файлы резервных копий, которые затем восстанавливаются с помощью соответствующего инструмента восстановления (например, mongorestore илиpg_restore). Они предлагают детальный контроль над тем, какие данные для резервного копирования и восстановления, а резервные копии часто переносимы между версиями и установками баз данных. Поскольку инструменты логического резервного копирования считывают все данные, резервные копии которых хранятся в памяти, они могут работать медленно и вызывать нетривиальную дополнительную нагрузку для особенно больших баз данных.

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

В этом руководстве мы продемонстрируем, как создать резервную копию базы данных MongoDB с помощьюmongodump, встроенного инструмента логического резервного копирования. Затем мы покажем, как сжать и загрузить полученные сериализованные файлы резервных копий данных вDigitalOcean Spaces, хранилище объектов с высокой степенью избыточности. Мы также покажем, как регулярно планировать операции резервного копирования и загрузки с помощью Bash иcron, и в заключение приведем пример сценария восстановления данных.

К концу этого руководства вы внедрили платформу для расширяемой стратегии автоматического резервного копирования, которая позволит вам быстро восстанавливаться, если ваше приложение будет страдать от потери данных. Для баз данных малого и среднего размера логическое резервное копирование с использованиемmongodump дает вам точный контроль над тем, какие данные нужно копировать и восстанавливать. Хранение этих сжатых архивов резервных копий в DigitalOcean Spaces гарантирует, что они легко доступны в долговременном хранилище объектов, чтобы данные вашего приложения были защищены и быстро восстанавливались в случае потери данных.

[.note] #Note: Использование инструментаmongodump может оказать некоторое влияние на производительность, особенно в сильно загруженных базах данных. Вы должны сначала протестировать эту процедуру, используя непроизводственную базу данных с имитацией нагрузки, чтобы убедиться, что этот метод будет работать в вашем производственном развертывании.
#

Предпосылки

Прежде чем начать работу с этим руководством, убедитесь, что у вас есть следующие предварительные условия:

После того, как вы вошли в свою Droplet, запустили и запустили MongoDB и создали свой Space, вы готовы начать.

[[step-1 -—- insert-test-data]] == Шаг 1. Вставьте тестовые данные

Если вы начинаете с чистой установки MongoDB и еще не сохранили никаких данных, вам следует сначала вставить некоторые образцы данных в фиктивную коллекциюrestaurants для тестирования. Если у вас уже есть несколько коллекций и документов, хранящихся в вашей базе данных, можете пропустить этот шаг и перейти кStep 2.

Сначала подключитесь к работающей базе данных с помощью оболочки MongoDB:

mongo

Вы увидите следующее приглашение оболочки Mongo:

MongoDB shell version: 3.2.19
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
    http://docs.mongodb.org/
Questions? Try the support group
    http://groups.google.com/group/mongodb-user
Server has startup warnings:
2018-04-11T20:30:57.320+0000 I CONTROL  [initandlisten]
2018-04-11T20:30:57.320+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2018-04-11T20:30:57.320+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2018-04-11T20:30:57.320+0000 I CONTROL  [initandlisten]
>

По умолчанию оболочка подключается к базе данныхtest.

Перечислим коллекции, присутствующие в базе данныхtest:

show collections

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

Давайте вставим документ в фиктивную коллекциюrestaurants, которая будет создана автоматически (так как ее еще нет):

db.restaurants.insert({'name': 'Pizzeria Sammy'})

Вы увидите следующий вывод:

OutputWriteResult({ "nInserted" : 1 })

Это указывает на то, что операция вставки прошла успешно.

Давайте еще раз перечислим коллекции:

show collections

Теперь мы видим нашу недавно созданную коллекциюrestaurants:

Outputrestaurants

Чтобы выйти из оболочки MongoDB, нажмитеCTRL +D.

Теперь, когда мы сохранили некоторые образцы данных в базе данных, мы готовы их сохранить.

[[step-2 -—- use-mongodump-to-back-up-mongodb-data]] == Шаг 2. Используйтеmongodump для резервного копирования данных MongoDB

Теперь мы воспользуемся встроенной утилитойmongodump для резервного копирования (или «дампа») всей базы данных MongoDB в сжатый архивный файл.

Во-первых, давайте создадим временный каталог с именемbackup для хранения архива, созданногоmongodump:

mkdir backup

Теперь давайте создадим резервную копию базы данныхtest в этом экземпляре MongoDB в сжатый архивный файл с именемtest_dump.gz. Если ваш экземпляр содержит другие базы данных, вы можете заменитьtest другим именем базы данных после флага--db. Вы также можете опустить флаг--db для резервного копирования баз данныхall в вашем экземпляре MongoDB.

[.note] #Note: Следующая команда должна быть запущена с терминала иnot оболочки Mongo.
#

mongodump --db test --archive=./backup/test_dump.gz --gzip

Здесь мы используем флаг--archive, чтобы указать, что мы хотели бы сохранить все данные в один архивный файл (местоположение которого указано параметромarchive), а--gzip флаг, чтобы указать, что мы хотим сжать этот файл. Кроме того, вы можете дополнительно использовать флаги--collection или--query, чтобы выбрать данную коллекцию или запрос для архивации. Чтобы узнать больше об этих флагах, обратитесь кmongodumpdocumentation.

После выполнения команды dump вы увидите следующий вывод:

Output2018-04-13T16:29:32.191+0000    writing test.restaurants to archive './backup/test_dump.gz'
2018-04-13T16:29:32.192+0000    done dumping test.restaurants (1 document)

Это указывает на то, что наши тестовые данные были успешно сброшены.

На следующем шаге мы загрузим этот резервный архив в хранилище объектов.

[[step-3 -—- upload-the-backup-archive-to-digitalocean-space]] == Шаг 3. Загрузите резервный архив в DigitalOcean Spaces

Чтобы загрузить этот архив в наш DigitalOcean Space, нам нужно будет использовать инструментs3cmd, который мы установили и настроили вPrerequisites.

Сначала мы протестируем нашу конфигурациюs3cmd и попытаемся получить доступ к нашему пространству для резервных копий. В этом уроке мы будем использоватьmongo-backup-demo в качестве имени пространства, но вы должны ввести его настоящее имя:

s3cmd info s3://mongo-backup-demo/

Вы увидите следующий вывод:

Outputs3://mongo-backup-demo/ (bucket):
   Location:  nyc3
   Payer:     BucketOwner
   Expiration Rule: none
   Policy:    none
   CORS:      none
   ACL:       3587522: FULL_CONTROL

Это означает, что соединение было успешным иs3cmd может передавать объекты в пространство.

Давайте перенесем архив, который мы создали на шаге 2, в наше пространство с помощью командыput:

s3cmd put ./backup/test_dump.gz s3://mongo-backup-demo/

Вы увидите некоторые результаты передачи файлов:

Outputupload: './backup/test_dump.gz' -> 's3://mongo-backup-demo/test_dump.gz'  [1 of 1]
 297 of 297   100% in    0s    25.28 kB/s  done

После завершения передачи мы проверим, что файл был успешно перенесен в наше пространство, перечислив содержимое этого пространства:

s3cmd ls s3://mongo-backup-demo/

Вы должны увидеть файл архива резервной копии:

Output2018-04-13 20:39       297   s3://mongo-backup-demo/test_dump.gz

На этом этапе вы успешно создали резервную копию базы данных MongoDBtest и передали архив резервных копий в свое пространство DigitalOcean.

В следующем разделе мы расскажем, как создать сценарий вышеупомянутой процедуры с помощью Bash, чтобы мы могли запланировать ее с помощьюcron.

[[step-4 -—- create-and-test-backup-script]] == Шаг 4. Создайте и протестируйте сценарий резервного копирования

Теперь, когда мы создали резервную копию нашей базы данных MongoDB в сжатый архивный файл и перенесли этот файл в наш Space, мы можем объединить эти шаги вручную в один скрипт Bash.

Создать резервный скрипт

Сначала мы напишем сценарий, объединяющий командыmongodump иs3cmd put, и добавим несколько дополнительных наворотов, таких как ведение журнала (с использованием `echo`s ').

Откройте пустой файл в любом текстовом редакторе (здесь мы будем использоватьnano):

nano backup_mongo.sh

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

Давайте рассмотрим этот скрипт по частям:

backup_mongo.sh

#!/bin/bash

set -e
...

Здесь#!/bin/bash указывает оболочке интерпретировать скрипт как код Bash. set -e сообщает интерпретатору немедленно выйти, если какая-либо из команд сценария не удалась.

backup_mongo.sh

...

SPACE_NAME=mongo-backup-demo
BACKUP_NAME=$(date +%y%m%d_%H%M%S).gz
DB=test

...

В этом разделе мы устанавливаем три переменные, которые будем использовать позже:

  • SPACE_NAME: имя пространства DigitalOcean, в которое мы загружаем файл резервной копии.

  • BACKUP_NAME: имя архива резервных копий. Здесь мы устанавливаем базовую строку даты и времени.

  • DB: указывает, для какой базы данных MongoDB будет создана резервная копия сценария. Если вы создаете резервную копию всего экземпляра MongoDB (всех баз данных), эта переменная не будет использоваться.

backup_mongo.sh

...

date
echo "Backing up MongoDB database to DigitalOcean Space: $SPACE_NAME"

echo "Dumping MongoDB $DB database to compressed archive"
mongodump --db $DB --archive=$HOME/backup/tmp_dump.gz --gzip

echo "Copying compressed archive to DigitalOcean Space: $SPACE_NAME"
s3cmd put $HOME/backup/tmp_dump.gz s3://$SPACE_NAME/$BACKUP_NAME

...

Затем мы печатаем дату и время (для ведения журнала) и начинаем резервное копирование, выполнив командуmongodump, которую мы тестировали выше. Еще раз сохраняем резервную копию архива в~/backup/.

Затем мы используемs3cmd, чтобы скопировать этот архив в место, указанное этими двумя переменнымиSPACE_NAME иBACKUP_NAME. Например, если имя нашего пространстваmongo-backup-demo, а текущая дата и время -2018/04/12 12:42:21, резервная копия будет называться180412_124221.gz, и она будет сохранена в пространствеmongo-backup-demo. .

backup_mongo.sh

...

echo "Cleaning up compressed archive"
rm $HOME/backup/tmp_dump.gz

echo 'Backup complete!'

Здесь мы удаляем архив резервных копий из каталога~/backup, поскольку мы успешно скопировали его в наше пространство, с окончательным выводом, указывающим, что резервное копирование завершено.

После объединения всех этих фрагментов кода полный сценарий должен выглядеть следующим образом:

backup_mongo.sh

#!/bin/bash

set -e

SPACE_NAME=mongo-backup-demo
BACKUP_NAME=$(date +%y%m%d_%H%M%S).gz
DB=test

date
echo "Backing up MongoDB database to DigitalOcean Space: $SPACE_NAME"

echo "Dumping MongoDB $DB database to compressed archive"
mongodump --db $DB --archive=$HOME/backup/tmp_dump.gz --gzip

echo "Copying compressed archive to DigitalOcean Space: $SPACE_NAME"
s3cmd put $HOME/backup/tmp_dump.gz s3://$SPACE_NAME/$BACKUP_NAME

echo "Cleaning up compressed archive"
rm $HOME/backup/tmp_dump.gz

echo 'Backup complete!'

Обязательно сохраните этот файл, когда закончите.

Далее мы протестируем этот скрипт, чтобы убедиться, что все подкоманды работают.

Скрипт тестового резервного копирования

Давайте быстро запустим сценарийbackup_mongo.sh.

Сначала сделайте скрипт исполняемым:

chmod +x backup_mongo.sh

Теперь запустите скрипт:

./backup_mongo.sh

Вы увидите следующий вывод:

OutputMon Apr 16 22:20:26 UTC 2018
Backing up MongoDB database to DigitalOcean Space: mongo-backup-demo
Dumping MongoDB test database to compressed archive
2018-04-16T22:20:26.664+0000    writing test.restaurants to archive '/home/sammy/backup/tmp_dump.gz'
2018-04-16T22:20:26.671+0000    done dumping test.restaurants (1 document)
Copying compressed archive to DigitalOcean Space: mongo-backup-demo
upload: '/home/sammy/backup/tmp_dump.gz' -> 's3://mongo-backup-demo/180416_222026.gz'  [1 of 1]
 297 of 297   100% in    0s     3.47 kB/s  done
Cleaning up compressed archive
Backup complete!

Мы успешно создали сценарий оболочки резервного копирования и теперь можем перейти к его планированию с помощьюcron.

[[step-5 -—- schedule-daily-backups-using-cron]] == Шаг 5. Планируйте ежедневное резервное копирование с помощью Cron

Чтобы запланировать ночной запуск сценария резервного копирования, мы будем использоватьcron, служебную программу планирования заданий, встроенную в Unix-подобные операционные системы.

Во-первых, мы создадим каталог для хранения журналов для нашего скрипта резервного копирования. Затем мы добавим сценарий резервного копирования в crontab (файл конфигурацииcron), чтобыcron запланировал его запуск на ночь. Посколькуcron поддерживает любую регулярную частоту, вы можете дополнительно запланировать еженедельное или ежемесячное резервное копирование.

Создать каталог журналов

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

Создайте подкаталогmongo_backup в/var/log (по соглашению, используемому для ведения журнала):

sudo mkdir /var/log/mongo_backup

Теперь сделайте этот каталог доступным для записи нашему пользователю Unix. В этом случае имя нашего пользователяsammy, но вы должны использовать соответствующее имя пользователя без полномочий root с привилегиями sudo для вашего сервера.

sudo chown sammy:sammy /var/log/mongo_backup

Наш пользователь Unixsammy теперь может писать в/var/log/mongo_backup. Поскольку задание cron будет работать какsammy, теперь оно может записывать свои файлы журнала в этот каталог.

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

Создать Cronjob

Чтобы создать задание cron, мы отредактируем файл, содержащий список запланированных заданий, который называется «crontab». Обратите внимание, что существует несколько crontab, по одному на пользователя, и общесистемный crontab в/etc/crontab. В этом руководстве мы запустим сценарий резервного копирования от имени нашего пользователяsammy; в зависимости от вашего варианта использования вы можете запустить его из общесистемного crontab.

Откройте crontab для редактирования:

crontab -e

Вы увидите следующее меню, позволяющее выбрать предпочитаемый текстовый редактор:

Outputno crontab for sammy - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/ed
  2. /bin/nano        <---- easiest
  3. /usr/bin/vim.basic
  4. /usr/bin/vim.tiny

Choose 1-4 [2]: no crontab for sammy - using an empty one

Выберите предпочтительный редактор; чтобы выбратьnano, введите2. Теперь добавьте следующую строку в файл, следуя закомментированному разделу:

crontab -e

# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

0 2 * * * /home/sammy/mongo_backup.sh >>/var/log/mongo_backup/mongo_backup.log 2>&1

Обязательно добавьте завершающий символ новой строки в конце crontab. Сохраните и закройте файл.

Вы увидите следующий вывод:

Outputno crontab for sammy - using an empty one
crontab: installing new crontab

Сценарий резервного копирования теперь будет выполняться в 2:00 утра каждое утро. Иstdout, иstderr (потоки вывода и ошибок) будут переданы по конвейеру и добавлены в файл журнала с именемmongo_backup.log в каталоге журнала, который мы создали ранее.

Вы можете изменить0 2 * * * (выполнять каждую ночь в 2:00 в синтаксисе cron) на желаемую частоту и время резервного копирования. Чтобы узнать больше о cron и его синтаксисе, обратитесь к нашему руководству поHow To Use Cron To Automate Tasks On A VPS.

Мы завершим это руководство быстрым восстановлением, чтобы убедиться, что наши резервные копии работают.

[[step-6 -—- perform-a-test-recovery]] == Шаг 6. Выполните тестовое восстановление

Любая стратегия резервного копирования должна содержать процедуру восстановления, которая регулярно проверяется. Здесь мы быстро протестируем восстановление из сжатого файла резервной копии, который мы загрузили в пространство DigitalOcean.

Сначала мы загрузимtest_dump.gz из нашего пространства в домашний каталог в нашей капле MongoDB:

s3cmd get s3://mongo-backup-demo/test_dump.gz

Вы увидите следующий вывод:

Outputdownload: 's3://mongo-backup-demo/test_dump.gz' -> './test_dump.gz'  [1 of 1]
 297 of 297   100% in    0s  1305.79 B/s  done

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

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

Подключитесь к своему экземпляру MongoDB с помощью оболочкиmongo:

mongo

Теперьuse база данныхtest и удалите ее из экземпляра MongoDB:

use test
db.dropDatabase()

Вы увидите следующий результат, подтверждающий падениеtest:

Output{ "dropped" : "test", "ok" : 1 }

Теперь выйдите из оболочкиmongo и выполните командуmongorestore:

mongorestore --gzip --archive=test_dump.gz --db test

Здесь мы указываем, что исходный файл резервной копии сжат и находится в форме «архивного файла» (напомним, что мы использовали флаги--archive и--gzip при вызовеmongodump), и что мы бы хотел восстановить базу данныхtest.

Вы увидите следующий вывод:

Output2018-04-16T23:10:07.317+0000    creating intents for archive
2018-04-16T23:10:07.453+0000    reading metadata for test.restaurants from archive 'test_dump.gz'
2018-04-16T23:10:07.497+0000    restoring test.restaurants from archive 'test_dump.gz'
2018-04-16T23:10:07.541+0000    restoring indexes for collection test.restaurants from metadata
2018-04-16T23:10:07.541+0000    finished restoring test.restaurants (1 document)
2018-04-16T23:10:07.541+0000    done

Это означает, что восстановлениеtest выполнено успешно.

В заключение подтвердим, что наши исходные данныеrestaurants успешно восстановлены.

Откройте оболочку MongoDB и запросите коллекциюrestaurants:

db.restaurants.find()

Вы должны увидеть объект, который мы сохранили в первом шаге этого урока:

Output{ "_id" : ObjectId("5ace7614dbdf8137afe60025"), "name" : "Pizzeria Sammy" }

Теперь вы успешно внедрили и протестировали эту стратегию резервного копирования MongoDB.

Заключение

В этом руководстве мы узнали, как реализовать и протестировать стратегию ночных логических резервных копий MongoDB.

Это руководство может быть расширено или изменено многими способами. Вот несколько быстрых предложений:

  • В зависимости от целей точки восстановления (RPO), вы можете увеличить или уменьшить предложенную частоту резервного копирования в соответствии с вашим окном восстановления данных.

  • Другим полезным дополнением была бы функция оповещения, запускаемая в случае сбоя подкоманды сценария резервного копирования (например, эта функция может отправлять электронную почту на входящие сообщения, которые регулярно контролируются).

  • Этот скрипт не обрабатывает удаление объекта Spaces. Вы можете очистить резервные копии старше, скажем, 6 месяцев или около того.

  • Вы можете захотеть реализовать более сложныйbackup rotation scheme, в зависимости от вашего производственного варианта использования.

Поскольку процедураmongodump включает быстрое чтение всех выгруженных данных, этот метод резервного копирования больше всего подходит для баз данных малого и среднего размера, особенно для частичных резервных копий, таких как конкретная коллекция или набор результатов. Резервные копии на уровне файловой системы рекомендуются для больших развертываний. Чтобы узнать больше о резервных копиях MongoDB на уровне файловой системы, обратитесь к этому руководству поHow To Back Up MongoDB Using Droplet Snapshots. Чтобы узнать больше о различных методах резервного копирования базы данных MongoDB, вы можете обратиться кMongoDB manual.

Решение, представленное в этом руководстве, используетmongodump для детального контроля над покрытием данных резервного копирования и DigitalOcean Spaces для экономичного и надежного долгосрочного хранения данных. Чтобы узнать больше об утилите резервного копированияmongodump, обратитесь к ееreference page в руководстве MongoDB. Чтобы узнать больше о DigitalOcean Spaces, вы можете прочитатьAn Introduction To DigitalOcean Spaces.

Related