Резервное копирование данных MySQL в хранилище с помощью снапшотов LVM
mySQL, Ubuntu | Комментировать запись
Регулярное резервное копирование – важный этап в защите данных. Разработка эффективной стратегии резервного копирования и восстановления почти всегда включает в себя поиск баланса между влиянием на производительность, затратами на внедрение и хранение данных, скоростью восстановления и целостностью данных. Оптимальное решение будет зависеть от точек восстановления, масштаба и архитектуры базы данных.
Данный мануал научит вас выполнять горячее резервное копирование рабочей БД MySQL с помощью снапшотов LVM и сохранять данные в удаленном хранилище.
Процедура, представленная в этом мануале, хорошо подходит для больших баз данных MySQL, баз данных, использующих смесь систем хранения (таких как InnoDB, TokuDB и MyISAM) и серверов баз данных с несколькими блочными хранилищами, управляемыми через LVM.
Для начала нужно убедиться, что сервер Ubuntu 16.04 может принимать и монтировать снапшоты LVM. Затем вы сможете сделать снапшот логического тома, содержащего каталог данных MySQL. Далее нужно смонтировать этот снапшот тома (замороженный логический том), скомпилировать и отправить каталог данных MySQL в хранилище. В конце мануала вы найдете примерный сценарий восстановления.
Требования
- Сервер Ubuntu 16.04, настроенный по этому мануалу.
- Рабочая установка MySQL 5.7+ (читайте Установка MySQL в Ubuntu 16.04).
- Логический том LVM для хранения данных MySQL. Больше полезной информации вы найдете в мануале Введение в LVM: основные понятия и операции. Чтобы научиться перемещать каталог данных MySQL, читайте Перемещение каталога данных MySQL в Ubuntu 16.04.
- s3-совместимое хранилище и учетные данные API.
- Клиент передачи файлов s3cmd (2.X), его установка описана в разделе 1 мануала Архивирование логов в удаленном хранилище объектов с помощью Logrotate и S3cmd в Ubuntu 16.04.
- s3cmd, настроенный на доступ к вашему хранилищу (как описано в мануале Настройка s3cmd 2.x для управления хранилищами).
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: LVM, MySQL, MySQL 5.7, S3, s3cmd, Ubuntu 16.04