Резервное копирование данных MySQL в хранилище с помощью снапшотов LVM

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

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

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

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

Требования

1: Изучение конфигурации MySQL и LVM

Для начала нужно найти каталог данных MySQL и собрать данные о настройках LVM.

Поиск datadir

Чтобы найти расположение каталога данных MySQL, введите:

mysqladmin -u root -p variables | grep datadir

Введите root-пароль MySQL, после чего вы увидите вывод:

| datadir                                                  | /data/mysql/

Каталог данных текущей установки MySQL располагается в /data/mysql.

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

lsblk
NAME             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, используемого в этом руководстве.

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

sudo pvscan
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
--- 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 ГБ, а группе томов vg1 – 25 ГБ. Строка Cur PV показывает, что в этой группе томов есть 1 физический том. Строка Cur LV указывает, что пул пространства в этой группе томов был использован для создания 1 логического тома.

Чтобы посмотреть на этот логический том, используйте lvdisplay:

sudo lvdisplay
--- 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 сообщает, что у нас есть один логический том объемом 475 ГБ, mysql_data, расположенный в /dev/vg1/mysql_data  (напомним, что vg1 – имя группы томов mysql_data).

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

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

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

Теперь нужно подготовить сервер базы данных к созданию снапшота LVM.

2: Подготовка сервера к созданию снапшота LVM

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

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

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

Увеличить текущий том можно с помощью панели управления хранилищем.

В панели отображаются все существующие тома и данные о них. Увеличьте объем тома до 100 Гб.

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

Войдите на сервер, а затем запустите pvscan, чтоб найти физические тома.

sudo pvscan

Вы получите такой же вывод, как ранее для /dev/sda:

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
Physical volume "/dev/sda" changed
1 physical volume(s) resized / 0 physical volume(s) not resized

Убедитесь, что объем тома изменился:

sudo pvscan

Теперь физический том /dev/sda имеет 600 Гб.

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
--- 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 Гб будет достаточно для обработки операций и изменений во время процедуры резервного копирования и загрузки, но в производственной среде размер тома снапшота должен масштабироваться пропорционально ожидаемому использованию диска в окне резервного копирования.

Теперь у вас достаточно пространства для проведения успешной процедуры создания снапшота.

3: Создание и монтирование снапшота LVM

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

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

Блокирование операций чтения в БД MySQL

Войдите в MySQL:

mysql -u root -p

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

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

FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)

Это означает, что ваша база данных заблокирована. Не выходите из командной строки MySQL.

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

Создание и монтирование тома снапшота

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

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

Теперь мы можем сделать снимок логического тома 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.

Вы увидите такой вывод:

Logical volume "mysql_data_snap" created.

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

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

UNLOCK TABLES;
Query 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:

lost+found  mysql

Теперь можно скопировать снимок в хранилище объектов.

4: Сжатие и загрузка файлов в хранилище объектов

Чтобы загрузить эту резервную копию в хранилище объектов, используйте инструмент s3cmd.

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

s3cmd info s3://mysql-backup-demo/
s3://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, который перемещает сжатый архив в хранилище. Сжатый архив называется mysql_backup_180423.tar.gz.

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

...
upload: '<stdin>' -> '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/
2018-04-23 20:39       297   s3://mysql-backup-demo/mysql_backup_180423.tar.gz

Физическое резервное копирование данных MySQL в хранилище объектов успешно завершено.

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

5: Демонтаж и сброс тома снапшота

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

Для этого введите:

sudo umount /backup_src

Вместо /backup_src укажите имя вашей точки монтирования.

Чтобы сбросить том, введите:

sudo lvremove vg1/mysql_data_snap

Здесь vg1 – это имя вашей группы томов, а mysql_data_snap – имя вашего снапшота.

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

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

Logical volume "mysql_data_snap" successfully removed

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

Давайте рассмотрим сценарий восстановления.

6: Тестовое восстановление физической резервной копии

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

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

s3cmd get s3://mysql-backup-demo/mysql_backup_180423.tar.gz ~/mysql_backup_180423.tar.gz
download: '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/*

Напоминаем, что в мануале используется нестандартное расположение каталога /data.

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

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

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

sudo service mysql start

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

mysql -u root -p

Введя пароль, вы увидите такой вывод:

Welcome 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>

Чтобы убедиться в целостности данных, просмотрите свои таблицы.

Заключение

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

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

Tags: , , , , ,