tgoop.com/srv_admin/4568
Last Update:
У меня уже были заметки про фишки LVM, сегодня расскажу про ещё одну, которая может пригодиться. С помощью LVM и снепшотов можно делать консистентные бэкапы баз данных Mysql на уровне файлов, а не дампов, практически без простоя. Для таких задач в СУБД Percona есть инструмент под названием XtraBackup, а вот если у вас обычная бесплатная MySQL или MariaDB, то с бэкапами на уровне файлов там не так всё просто, особенно если вы уже не можете делать дампы из-за их больших размеров.
Идея там вот в чём. Мы закрываем все открытые таблицы, сбрасываем кэш, блокируем изменение данных, после этого делаем снепшот раздела с базами данных и сразу отключаем блокировки. Это занимает буквально пару секунд, на которые блокируются все базы, а потом спокойно копируем файлы сервера, примонтировав снепшот.
Это всё хорошо работало до появления движка InnoDB. У него есть нюансы, когда блокировки не предотвращают изменение данных в таблицах. Нужно дополнительно сбрасывать на диск так называемые dirty_pages. Покажу всё это на практике. Способ немного костыльный и вряд ли подойдёт для прода, так как есть много нюансов. Но в каких-то ситуациях может помочь быстро снять консистентную копию без остановки сервера.
Для того, чтобы всё получилось, раздел, где хранятся данные MySQL сервера, должен располагаться на LVM, а в Volume Group должно быть свободное место для снепшотов. Проверяем так:# pvs
Если места нет, надо добавить. Не буду на этом останавливаться, рассказывал ранее. Первым делом заходим в консоль mysql, сбрасываем кэш и включаем блокировки:> SET GLOBAL innodb_max_dirty_pages_pct = 0;
> FLUSH TABLES WITH READ LOCK;
Если база не сильно большая и нагруженная, кэш быстро сбросится. Наблюдать можно так:> SHOW ENGINE INNODB STATUS\G;
Следим за значением Modified db pages
. Оно должно стать 0
. После этого можно делать снэпшот:# lvcreate --size 5G --snapshot --name mysql_snapshot /dev/vgroup/root
После этого возвращаем обратно настройку с dirty_pages в исходное значение (по умолчанию 90) и снимаем блокировки:> SET GLOBAL innodb_max_dirty_pages_pct = 90;
> UNLOCK TABLES;
Когда это делается автоматически скриптом, всё это происходит быстро. Но есть нюансы. Команда блокировки дожидается завершения всех запросов. Если у вас там есть какие-то очень длинные запросы, то вся база будет заблокирована, пока они не завершатся. Так что имейте это ввиду.
Монтируем снепшот и копируем данные:# mkdir /mnt/mysql_backup
# mount /dev/vgroup/mysql_snapshot /mnt/mysql_backup
# rsync -avz --delete /mnt/mysql_backup/var/lib/mysql/ [email protected]:/mnt/backup/mysql/
После копирования снепшот надо обязательно удалить. # umount /mnt/mysql_backup
# lvremove -f /dev/vgroup/mysql_snapshot
Получили консистентный бэкап всех баз данных практически без остановки сервера, но с кратковременной блокировкой изменений.
Я собрал всё это в скрипт и протестировал на сервере с MariaDB и Zabbix Server. Сохранил бэкап локально, потом остановил MariaDB, полностью удалил директорию /var/lib/mysql
и восстановил из бэкапа. Потом запустил СУБД. Запустилось без проблем, никаких ошибок. Бэкап получается консистентный.
Скрипт особо не отлаживал, так что аккуратнее с ним. Просто убедился, что работает. Сначала немного накосячил, так как после включения блокировки закрывал сессию, делал снепшот и подключался снова. Так нельзя, потому что команда FLUSH TABLES WITH READ LOCK
живёт, пока открыто соединение. Надо в рамках него делать всё необходимое. Запустил lvcreate через SYSTEM.
Такой вот небольшой трюк в копилку LVM, который можно применять не только к СУБД, но и другим данным.
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#lvm #mysql #backup
BY ServerAdmin.ru

Share with your friend now:
tgoop.com/srv_admin/4568