Как сделать резервную копию базы данных MySQL в пространстве DigitalOcean с помощью снимков LVM

Вступление

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

В этом руководстве мы покажем, как выполнить оперативное (или «горячее») физическое резервное копирование работающей базы данных MySQL с использованием снимков LVM. Затем мы сжимаем и храним данные в DigitalOcean Space.

Процедура, представленная в этом руководстве, хорошо подходит для больших баз данных MySQL, баз данных, использующих различные механизмы хранения (таких как InnoDB, TokuDB и MyISAM), и серверов баз данных с несколькими подключенными томами хранилища, управляемых с помощью LVM.

Начнем с того, что наш сервер Ubuntu 16.04 сможет сделать и смонтировать моментальный снимок LVM. Далее мы сделаем снимок LVM логического тома, содержащего каталог данных MySQL. Затем мы смонтируем этот том моментального снимка (замороженный логический том), сжимаем и отправляем каталог данных MySQL в DigitalOcean Spaces для хранения. В заключение кратко рассмотрим пример сценария восстановления.

Предпосылки

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

Как только вы все это настроите, вы готовы начать с этого руководства.

[[step-1 -—- study-mysql-and-lvm-configuration]] == Шаг 1. Изучение конфигурации MySQL и LVM

Для начала мы найдем наш каталог данных MySQL и отметим эти детали о нашей конфигурации LVM.

Найдите MySQLdatadir

Чтобы найти путь к вашему каталогу данных MySQL, выполните следующую команду:

mysqladmin -u root -p variables | grep datadir

При появлении запроса введите пароль MySQLroot. Вы должны увидеть вывод, похожий на следующий:

Output| datadir                                                  | /data/mysql/

Для установки MySQL, используемой в этом руководстве, каталог данных -/data/mysql.

Теперь нам нужно подтвердить, что/data/mysql находится на логическом томе LVM. Чтобы убедиться в этом, запустимlsblk:

lsblk

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

OutputNAME             MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                8:0    0   600G  0 disk
└─vg1-mysql_data 252:0    0   475G  0 lvm  /data
vda              253:0    0   160G  0 disk
├─vda1           253:1    0 159.9G  0 part /
├─vda14          253:14   0     4M  0 part
└─vda15          253:15   0   106M  0 part /boot/efi

Отсюда мы видим, что/data на самом деле является точкой монтирования для логического тома LVM с именемmysql_data. Он входит в группу томовvg1.

Теперь нам нужно убедиться, что у нас достаточно свободного места в нашей группе томовvg1, чтобы сделать снимок LVM.

Изучите конфигурацию LVM

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

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

sudo pvscan

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

Output  PV /dev/sda   VG vg1             lvm2 [500.00 GiB / 25.00 GiB free]
  Total: 1 [500.00 GiB] / in use: 1 [500.00 GiB] / in no VG: 0 [0   ]

Мы видим, что у нас есть один физический том 500 ГБ (/dev/sda), который находится в одной группе томов (vg1). 475 ГБ этого физического тома было выделено логическим томам, а 25 ГБ остается свободным для использования группой томов.

Мы можем подтвердить это, более детально изучив группу томовvg1 с помощью командыvgdisplay:

sudo vgdisplay

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

Output--- Volume group ---
  VG Name               vg1
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  2
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               500.00 GiB
  PE Size               4.00 MiB
  Total PE              127999
  Alloc PE / Size       121600 / 475.00 GiB
  Free  PE / Size       6399 / 25.00 GiB
  VG UUID               KEsoDE-zON7-NdyO-ioxb-6FSl-CB4m-S3QCRj

Из строкAlloc PE / Size иFree PE / Size мы видим, что у нас выделено 475 ГБ и 25 ГБ свободно в группе томовvg1. СтрокаCur PV показывает нам, что у нас есть 1 физический том в этой группе томов. СтрокаCur LV указывает, что мы использовали пул пространства в этой группе томов для создания 1 логического тома.

Давайте теперь посмотрим на этот логический том, используяlvdisplay:

sudo lvdisplay

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

Output  --- Logical volume ---
  LV Path                /dev/vg1/mysql_data
  LV Name                mysql_data
  VG Name                vg1
  LV UUID                T98x9c-zvC1-f0Rw-4ipn-Cxo2-duwk-KUwQQc
  LV Write Access        read/write
  LV Creation host, time LVM, 2018-04-18 20:11:48 +0000
  LV Status              available
  # open                 1
  LV Size                475.00 GiB
  Current LE             121600
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           252:0

ИзLV Size мы видим, что у нас есть один логический томmysql_data емкостью 475 ГБ, найденный в/dev/vg1/mysql_data (напомним, чтоvg1 было именем группы томовmysql_data).

Подводя итог, на сервере Ubuntu 16.04, используемом для этого руководства, у нас есть один физический том 500 ГБ (/dev/sda), используемый для поддержки одной группы томов (vg1), из которой мы создали одну логическую емкость 475 ГБ. объем (mysql_data). В результате в группе томов остается 25 ГБ свободного места, которое можно использовать для создания дополнительных логических томов (и снимков).

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

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

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

[[step-2 -—- prepare-your-server-for-lvm-snapshots]] == Шаг 2. Подготовьте свой сервер для создания снимков LVM

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

На предыдущем этапе мы заметили, что в группе томов (vg1), содержащей наш основной логический том (mysql_data), было свободно только 25 ГБ. Хотя может случиться так, что 25 ГБ изменений не будут записаны на диск за время, необходимое для резервного копирования нашей базы данных, в идеале мы хотели бы иметь запас прочности не менее 100 ГБ. В производственных условиях рекомендуется измерять средний объем данных, записываемых на диск во время запланированного резервного копирования, и соответствующим образом масштабировать размер тома снимка.

Чтобы добавить дополнительные 75 ГБ пространства к группе томовvg1, мы можем либо подключить блочное запоминающее устройство, либо увеличить размер тома, который в настоящее время прикреплен к капле. В этом руководстве мы расширим уже подключенный объем блочного хранилища; чтобы узнать больше о подключении дополнительного тома блочного хранилища, вы можете обратиться кAn Introduction to DigitalOcean Block Storage.

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

Давайте расширим объем блочного хранилища, прикрепленного к этой капле.

Перейдите к веб-панели управления DigitalOcean и с панели инструментов перейдите к своей капле.

На боковой панели щелкнитеVolumes:

Sidebar

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

Block Storage Volume

ЩелкнитеMore, а затемResize volume.

Отсюда вы можете выбрать один из нескольких предопределенных размеров тома или выбрать свой собственный размер тома. Давайте увеличим объем 500 ГБ на 100 ГБ до 600 ГБ:

Resize Volume

НажмитеContinue. Объем подключенного блока теперь увеличен на 100 ГБ.

Чтобы распространить это изменение устройства на LVM, нам нужно запуститьpvresize.

Войдите на свой сервер и снова запуститеpvscan для поиска физических томов:

sudo pvscan

Вы должны увидеть тот же результат, что и раньше, для нашего физического тома/dev/sda:

Output PV /dev/sda   VG vg1             lvm2 [500.00 GiB / 25.00 GiB free]
  Total: 1 [500.00 GiB] / in use: 1 [500.00 GiB] / in no VG: 0 [0   ]

Теперь запуститеpvresize на томе, чтобы заполнить только что добавленное пространство:

sudo pvresize /dev/sda

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

OutputPhysical volume "/dev/sda" changed
1 physical volume(s) resized / 0 physical volume(s) not resized

Давайте подтвердим, что наш физический том теперь на 100 ГБ больше, запустив еще одинpvscan:

sudo pvscan

Мы видим, что физический том/dev/sda теперь составляет 600 ГБ:

Output PV /dev/sda   VG vg1             lvm2 [600.00 GiB / 125.00 GiB free]
 Total: 1 [600.00 GiB] / in use: 1 [600.00 GiB] / in no VG: 0 [0   ]

Теперь давайте подтвердим, что свободное пространство нашей группы томов также увеличилось на 100 ГБ:

sudo vgdisplay

Затем вы должны увидеть следующий вывод:

Output  --- Volume group ---
  VG Name               vg1
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               600.00 GiB
  PE Size               4.00 MiB
  Total PE              153599
  Alloc PE / Size       121600 / 475.00 GiB
  Free  PE / Size       31999 / 125.00 GiB
  VG UUID               KEsoDE-zON7-NdyO-ioxb-6FSl-CB4m-S3QCRj

Это означает, что теперь у нас есть 125 ГБ свободного пространства, из которого можно создать том моментального снимка.

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

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

[[step-3 -—- create-and-mount-lvm-snapshot]] == Шаг 3 - Создайте и смонтируйте снимок LVM

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

Теперь создадим снимок логического томаmysql_data с помощьюlvcreate. Прежде чем мы это сделаем, нам нужно заморозить запись в базу данных с помощьюFLUSH TABLES WITH READ LOCK, чтобы мы могли гарантировать согласованность данных. Таблицы нужно только заблокировать для чтения, пока мы не запустимlvcreate, после чего их можно будет разблокировать. Если вы выполняете сценарий этой серии команд, общее время блокировки должно быть очень маленьким, в зависимости от выполняемых в данный момент запросов записи.

Чтение блокировки базы данных MySQL

Давайте начнем с очистки таблиц. В терминале на сервере базы данных используйтеmysql для входа в базу данных MySQL:

mysql -u root -p

В оболочке MySQL запустите командуFLUSH TABLES, чтобы заблокировать вашу базу данных на чтение.

[.warning] #Warning: После выполнения следующей команды все открытые таблицы будут закрыты, а все таблицы для всех баз данных будут заблокированы глобальной блокировкой чтения. Если это выполняется в производственной базе данных, лучше всего выполнить эту команду на реплике или как часть сценария, чтобы минимизировать время блокировки базы данных.
#

FLUSH TABLES WITH READ LOCK;

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

OutputQuery OK, 0 rows affected (0.00 sec)

Что указывает на то, что ваша база данных была заблокирована для чтения. Не закрывайте приглашение MySQL, нам нужно держать его открытым.

Теперь мы создадим и смонтируем снимок LVM логического тома, используемого для хранения наших данных MySQL.

Создать и смонтировать том снимка

Оставив открытым клиентское соединение MySQL, войдите на сервер базы данных из нового окна терминала.

[.warning] #Warning: Если вы закроете это соединение, блокировка будет снята, и запись возобновится, что сделает снимок несовместимым.
#

Теперь мы можем сделать снимок логического томаmysql_data. Мы выделим 100 ГБ буферного пространства для поглощения записей и других изменений при выполнении физического резервного копирования. Чтобы создать снимок LVM, выполните следующую командуlvcreate:

sudo lvcreate -L 100G -s -n mysql_data_snap /dev/vg1/mysql_data

Флаг-L указывает размер логического тома, в данном случае 100 ГБ. -s указывает, что логический том будет снимком, в данном случае логическим томом/dev/vg1/mysql_data. Мы решили назвать этот том моментального снимкаmysql_data_snap.

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

OutputLogical volume "mysql_data_snap" created.

Это означает, что теперь у нас есть копия логического томаmysql_data, с которого мы можем выполнить резервное копирование.

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

UNLOCK TABLES;

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

OutputQuery OK, 0 rows affected (0.00 sec)

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

На данный момент ваша база данных все еще активна и принимает входящие соединения и записи, но у нас есть согласованный снимок данных в тот момент времени, когда мы запускалиFLUSH TABLES WITH READ LOCK (или, чтобы быть полностью точным, момент времени, когда последний запрос записи после завершенияFLUSH).

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

Сначала мы создадим точку монтирования/backup_src:

sudo mkdir /backup_src

Теперь мы подключим том с моментальным снимком к/backup_src:

sudo mount /dev/vg1/mysql_data_snap /backup_src

Теперь мы можем получить доступ к замороженным файлам данных. Давайте взглянем:

cd /backup_src
ls

Вы должны увидеть ваш каталог данных MySQL:

Outputlost+found  mysql

Теперь, когда у нас есть доступ к непротиворечивому снимку наших данных, мы можем сделать его резервную копию в DigitalOcean Space.

[[step-4 -—- compress-and-upload-files-to-digitalocean-Space]] == Шаг 4. Сжатие и загрузка файлов в DigitalOcean Spaces

Чтобы загрузить эту резервную копию в наш DigitalOcean Space, мы воспользуемся инструментомs3cmd, который мы установили и настроили вprerequisite steps.

Сначала мы протестируем нашу конфигурациюs3cmd и попытаемся получить доступ к нашему пространству резервных копий (в этом руководстве наше пространство называетсяmysql-backup-demo):

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

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

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

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

Теперь мы сжимаем и загружаем наш каталог данных MySQL в пространствоmysql-backup-demo:

sudo tar -czvf - /backup_src/mysql | s3cmd put - s3://mysql-backup-demo/mysql_backup_180423.tar.gz

Здесь мы используемtar для сжатия и архивирования каталога данных MySQL и направляем вывод вs3cmd, который мы используем для передачи сжатого архива в Spaces. Мы назвали сжатый архивmysql_backup_180423.tar.gz.

Поскольку мы использовалиtar в подробном режиме, вы увидите список сжимаемых файлов (чтобы скрыть этот вывод, опустите флаг-v в приведенной выше команде).

Вывод завершится следующей информацией о передаче файла:

Output...
upload: '' -> 's3://mysql-backup-demo/mysql_backup_180423.tar.gz'  [part 1, 1417kB]
 1451996 of 1451996   100% in    0s  1993.41 kB/s  done

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

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

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

Output2018-04-23 20:39       297   s3://mysql-backup-demo/mysql_backup_180423.tar.gz

На данный момент мы успешно завершили физическое резервное копирование MySQL в DigitalOcean Spaces.

Теперь мы размонтируем и отбросим том с моментальным снимком, восстановив использованное пространство в нашей группе томовvg1.

[[step-5 -—- unmount-and-drop-snapshot-volume]] == Шаг 5 - Отключить и удалить том моментального снимка

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

Чтобы отключить том, выполните следующую команду:

sudo umount /backup_src

Замените/backup_src точкой монтирования тома с моментальным снимком.

Теперь мы можем сбросить объем снимка. Для этого выполните следующую команду:

sudo lvremove vg1/mysql_data_snap

Здесьvg1 соответствует имени вашей группы томов, аmysql_data_snap - имени вашего тома моментального снимка.

Вам будет предложено подтвердить удаление, на что вы должны ответитьY.

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

Output Logical volume "mysql_data_snap" successfully removed

Том снимка успешно удален. Вы завершили полное физическое резервное копирование MySQL и загрузили его в DigitalOcean Space.

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

[[step-6 -—- test-restore-from-physical-backup]] == Шаг 6. Тестовое восстановление из физической резервной копии

Чтобы восстановить нашу базу данных MySQL из физической резервной копии, которую мы ранее загрузили в Spaces, мы перенесем резервную копию на наш сервер базы данных, а затем используем извлеченные файлы в качестве нашего восстановленного каталога данных MySQL.

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

s3cmd get s3://mysql-backup-demo/mysql_backup_180423.tar.gz ~/mysql_backup_180423.tar.gz

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

Outputdownload: 's3://mysql-backup-demo/mysql_backup_180423.tar.gz' -> '~/mysql_backup_180423.tar.gz'  [1 of 1]
 1451889 of 1451889   100% in    0s    38.49 MB/s  done

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

Сначала остановите сервер MySQL:

sudo service mysql stop

Теперь удалите содержимое вашего каталога данных MySQL:

sudo rm -rf /data/*

Напомним, что в этом руководстве нестандартный путь к каталогу данных MySQL -/data.

Теперь распакуйте архив физической резервной копии в каталог данных MySQL:

sudo tar -xzvf ~/mysql_backup_180423.tar.gz -C /data

Теперь, когда файлы данных восстановлены, мы можем перезапустить базу данных MySQL и разрешить ее восстановление:

sudo service mysql start

Наконец, мы можем войти на наш сервер базы данных, чтобы убедиться, что восстановление завершено успешно:

mysql -u root -p

После ввода пароля вы должны увидеть приглашение клиента MySQL:

OutputWelcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.21-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

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

Заключение

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

В производственных условиях эта процедура в идеале должна составляться по сценарию и планироваться с надлежащей регистрацией, мониторингом и оповещениями. Кроме того,FLUSH TABLES WITH READ LOCK (неважно насколько коротким) следует запускать не на главном сервере, а на минимально загруженной реплике. Обратите внимание, что с небольшими изменениями вы также можете адаптировать описанную выше процедуру, чтобы быстро раскрутить реплики из главной физической резервной копии.

Если ваш экземпляр MySQL использует исключительно InnoDB в качестве механизма хранения, вы также можете использовать Percona XtraBackup для аналогичного выполнения физического резервного копирования вашей базы данных. Чтобы узнать больше, обратитесь к нашему руководству поHow To Back Up MySQL Databases to Object Storage with Percona on Ubuntu 16.04.

Разумной альтернативой загрузке физических файлов резервных копий в Spaces было бы использование снимков LVM в сочетании с снимками капель. Чтобы узнать больше о снимках капель, обратитесь кDigitalOcean Backups and Snapshots Explained.

Чтобы узнать больше о DigitalOcean Spaces, хранилище объектов, используемом в этом руководстве, обратитесь кAn Introduction To DigitalOcean Spaces.

Related