ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

Горячие бэкапы на VDS: LVM snapshots для файлов и баз данных

Хотите снимать горячие бэкапы на VDS без простоя? Разбираем LVM snapshots для файловых систем и MySQL: как подготовить VG/LV, безопасно применить fsfreeze и FTWRL, получить консистентный mysql backup, смонтировать снапшот, выгрузить и выполнить restore. Плюс тюнинг, автоматизация и проверка.
Горячие бэкапы на VDS: LVM snapshots для файлов и баз данных

Горячие бэкапы — это резервные копии, которые снимаются на работающем сервере без остановки приложений. На VDS такой подход особенно ценен: планирование простоев сложно, а короткие окна обслуживания часто невозможны. В этой статье показываю рабочий рецепт горячего backup с помощью LVM snapshots для файловых систем и консистентного mysql backup, с опорой на fsfreeze и минимальное время блокировки. Разберём подготовку LVM, практические шаги, типичные ловушки и восстановление (restore).

Когда и зачем использовать LVM snapshots

LVM снапшоты — это снимки состояния блочного устройства на момент времени. Они работают по Copy-on-Write: при изменении исходного тома копируется старая версия изменяемых блоков в отдельно выделенное пространство снапшота. Отсюда следуют плюсы: мгновенное создание, возможность монтировать снапшот в ro и спокойно вычитывать данные в архив. И минусы: пока существует снапшот, запись в оригинальный том замедляется, а если место под снапшот закончится, он станет непригодным.

Сценарии, где LVM особенно полезен:

  • Горячие копии директорий сайтов, медиа и конфигов, когда остановка сервисов нежелательна.
  • Физический mysql backup для InnoDB с минимальным временем read lock, удобный для быстрого restore или развертывания стендов.
  • Контрольные точки перед обновлением (с возможностью отката lvconvert --merge).

Важно: LVM снапшот фиксирует состояние блочного устройства, а не приложения. Для полной согласованности баз данных требуется короткая фаза «заморозки» — см. блок про MySQL.

Предварительная проверка: есть ли LVM и хватает ли места

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

lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT,LVM
vgs -o vg_name,vg_size,vg_free
lvs -o lv_name,vg_name,lv_size,lv_attr

Нам нужна свободная емкость в VG (Volume Group) для пространства снапшота. Правило большого пальца: размер снапшота ≈ ожидаемому объему изменений на исходном LV за время жизни снапшота с запасом. Для файлового архива на несколько минут обычно хватает 1–10% от размера LV, но всё зависит от интенсивности записи.

План: какие тома снимем и как будем вычитывать

Определите, что именно архивируем: том с данными сайтов (например, /var/www), том с логами, том с /var/lib/mysql. Для XFS и ext4 подход одинаков, но есть нюансы монтирования снапшота XFS: нужен параметр nouuid.

Далее выбираем стратегию выгрузки снапшота: tar в файл, поток в удаленное хранилище, rsync в каталог с дедупликацией, или подключение к инструментам версиирования. Снапшот сам по себе жить долго не должен — создали, смонтировали, вычитали, удалили. Подробнее о вариантах хранения см. гайд по S3‑бэкапам restic/borg.

Схема: VG/LV, снапшот, монтирование и выгрузка в бэкап

Быстрый старт: горячий бэкап каталога на ext4/XFS

Предположим, данные в /mnt/data, это отдельный LV /dev/vg/data. Шаги:

  1. Уточняем файловую систему:
findmnt -no FSTYPE /mnt/data
  1. Замораживаем ФС на 1–3 секунды (чтобы записать на диск все метаданные):
# Для XFS
xfs_freeze -f /mnt/data

# Для ext4
fsfreeze -f /mnt/data
  1. Создаём снапшот нужного размера (пример 5ГиБ):
lvcreate -L 5G -s -n data_snap /dev/vg/data
  1. Размораживаем ФС:
# XFS
xfs_freeze -u /mnt/data

# ext4
fsfreeze -u /mnt/data
  1. Монтируем снапшот только для чтения:
mkdir -p /mnt/snap
# Для XFS важно указать nouuid
mount -o ro,nouuid /dev/vg/data_snap /mnt/snap
# Для ext4 можно просто
# mount -o ro /dev/vg/data_snap /mnt/snap
  1. Выгружаем в архив или зеркало:
# Архив tar с атрибутами и ACL
cd /mnt/snap
 tar --xattrs --acls -cpf - . | gzip -1 > /backups/data-$(date +%F).tar.gz

# Или rsync в каталог с датой
rsync -aHAX --delete /mnt/snap/ /backups/data-$(date +%F)/
  1. Чистим за собой:
umount /mnt/snap
lvremove -y /dev/vg/data_snap

Снапшот держите как можно меньше по времени. Чем он живёт дольше, тем сильнее падает производительность исходного тома из‑за Copy‑on‑Write.

Консистентный MySQL backup через LVM snapshot

Для InnoDB корректный физический бэкап делается так: коротко блокируем записи в MySQL, замораживаем ФС с fsfreeze на время создания снапшота, снимаем снапшот, сразу же возвращаем MySQL в нормальный режим. Важные предпосылки:

  • Данные MySQL находятся на отдельном LV (рекомендовано) и директория datadir известна, чаще всего /var/lib/mysql.
  • Основные таблицы — InnoDB; для MyISAM и прочего потребуются более строгие блокировки, лучше мигрировать в InnoDB.
  • Журналирование транзакций включено стандартно; опции согласованы с безопасным режимом (innodb_flush_log_at_trx_commit=1, sync_binlog=1 — желательно).

Пошагово

  1. Уточните datadir и LV:
mysql --version
grep -i '^datadir' /etc/mysql/*.cnf /etc/my.cnf 2>/dev/null || echo "check service unit"
lsblk -o NAME,MOUNTPOINT,LVM | grep mysql || findmnt /var/lib/mysql
  1. Откройте интерактивную сессию MySQL и выполните блокировку чтения/записи, не закрывая сессию (это критично — пока сессия открыта, замок держится):
mysql -uroot -p
FLUSH TABLES WITH READ LOCK;
FLUSH LOGS;
-- при репликации можно зафиксировать позицию:
SHOW MASTER STATUS;
  1. Во втором окне терминала заморозьте ФС, создайте снапшот и сразу разморозьте:
# Если ФС XFS
xfs_freeze -f /var/lib/mysql
lvcreate -L 5G -s -n mysql_snap /dev/vg/mysql
xfs_freeze -u /var/lib/mysql

# Если ext4
fsfreeze -f /var/lib/mysql
lvcreate -L 5G -s -n mysql_snap /dev/vg/mysql
fsfreeze -u /var/lib/mysql
  1. Вернитесь в первую сессию MySQL и снимите блокировку:
UNLOCK TABLES;
  1. Смонтируйте снапшот в ro и выгрузите:
mkdir -p /mnt/mysqlsnap
mount -o ro,nouuid /dev/vg/mysql_snap /mnt/mysqlsnap  # для XFS
# mount -o ro /dev/vg/mysql_snap /mnt/mysqlsnap       # для ext4

# Важно копировать весь datadir, включая ibdata*, ib_logfile*, undo*, redo* и служебные каталоги
rsync -aHAX /mnt/mysqlsnap/ /backups/mysql-$(date +%F)/

umount /mnt/mysqlsnap
lvremove -y /dev/vg/mysql_snap

Почему нужен двойной «замок» (FTWRL + fsfreeze)? FTWRL останавливает изменения на уровне СУБД, а fsfreeze фиксирует на диске состояние ФС, чтобы LVM снапшот гарантированно отражал согласованные метаданные. Блокировка держится считанные секунды.

Советы и частые нюансы

  • Не исключайте файлы redo/undo/ibdata — это физический mysql backup, нужен полный datadir.
  • При восстановлении на другой сервер удалите или замените auto.cnf, чтобы избежать конфликта UUID.
  • Если в базе есть MyISAM, FTWRL обязателен; любые фоновые записи в эти таблицы должны быть остановлены.
  • Репликацию можно синхронизировать: сохраните координаты из SHOW MASTER STATUS вместе с копией; подробнее см. гайд по репликации GTID/semisync.

Последовательность FTWRL + fsfreeze для консистентного MySQL бэкапа

Восстановление (restore) из бэкапа

Файловые данные

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

rsync -aHAX --delete /backups/data-2025-01-10/ /mnt/data/

Быстрый откат LV на момент снапшота (если вы оставили снапшот ради отката):

umount /mnt/data
lvconvert --merge /dev/vg/data_snap
mount /mnt/data

Помните: для lvconvert --merge снапшот должен быть неактивен и исходный LV — отключен/отмонтирован.

MySQL

Восстановление физического бэкапа:

systemctl stop mysql
mv /var/lib/mysql /var/lib/mysql.bak.$(date +%s)
rsync -aHAX /backups/mysql-2025-01-10/ /var/lib/mysql/
chown -R mysql:mysql /var/lib/mysql
# Для SELinux
command -v restorecon && restorecon -Rv /var/lib/mysql || true
systemctl start mysql
journalctl -u mysql -e --no-pager

Если поднимали реплику, проверьте auto.cnf (UUID), а также конфигурацию server-id и подключение к источнику. Для восстановления до точки во времени используйте бинлоги согласно сохранённым координатам.

Размер снапшота и контроль заполнения

Пока живёт снапшот, все записываемые блоки исходного LV дублируются в его COW‑область. Следите за заполнением:

lvs -o lv_name,lv_attr,Data%,Cpy%Sync

Поле Data% у снапшота должно оставаться далёким от 100%. Если достигнет 100%, снапшот станет непригоден и монтироваться перестанет. Подбирайте размер с запасом и держите снапшот недолго.

Производительность и влияние на сервисы

Снапшот добавляет накладные расходы на запись. На загруженных дисках это заметно. Практика:

  • Создавайте снапшот на время копирования и удаляйте сразу после.
  • Планируйте бэкап на часы с минимальной нагрузкой.
  • Для сильно записываемых томов рассмотрите LVM thin snapshots (если используете thin-pool), они эффективнее по месту и скорости на множественных снимках.
FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Thin-пулы и thin snapshots (коротко)

Если ваши тома — thin LVs, команда создания снапшота остаётся практически той же, но снапшот будет типа thin-snapshot и использовать thin-pool. Пример создания тонкого пула и тома:

# Создать thin-pool на 100G
lvcreate -L 100G -T vg/thinpool
# Создать thin-том 50G
lvcreate -V 50G -T vg/thinpool -n data
# Снапшот thin-тома
lvcreate -s -n data_snap vg/data

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

Автоматизация: безопасный скрипт

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

#!/usr/bin/env bash
set -Eeuo pipefail
LOCK=/run/backup.lock
exec 9>&1 1>>/var/log/backup.log 2>&1
{
  flock -n 200 || { echo "Already running"; exit 1; }
} 200>"$LOCK"

echo "=== $(date -Is) backup start"
VG="vg"
LV_DATA="data"
LV_MYSQL="mysql"
SNAP_DATA="data_snap"
SNAP_MYSQL="mysql_snap"
BACKDIR="/backups/$(date +%F)"
mkdir -p "$BACKDIR"

# 1) DATA
xfs_freeze -f /mnt/data || fsfreeze -f /mnt/data || true
lvcreate -L 5G -s -n "$SNAP_DATA" "/dev/$VG/$LV_DATA"
xfs_freeze -u /mnt/data || fsfreeze -u /mnt/data || true
mkdir -p /mnt/snap_data
mount -o ro,nouuid "/dev/$VG/$SNAP_DATA" /mnt/snap_data || mount -o ro "/dev/$VG/$SNAP_DATA" /mnt/snap_data
rsync -aHAX --delete /mnt/snap_data/ "$BACKDIR/data/"
umount /mnt/snap_data
lvremove -y "/dev/$VG/$SNAP_DATA"

# 2) MYSQL
mysql -uroot -p"${MYSQL_ROOT_PASSWORD:-}" -e "FLUSH TABLES WITH READ LOCK; FLUSH LOGS;" &
LOCKPID=$!
sleep 1
xfs_freeze -f /var/lib/mysql || fsfreeze -f /var/lib/mysql
lvcreate -L 5G -s -n "$SNAP_MYSQL" "/dev/$VG/$LV_MYSQL"
xfs_freeze -u /var/lib/mysql || fsfreeze -u /var/lib/mysql
mysql -uroot -p"${MYSQL_ROOT_PASSWORD:-}" -e "UNLOCK TABLES;" || true

mkdir -p /mnt/snap_mysql
mount -o ro,nouuid "/dev/$VG/$SNAP_MYSQL" /mnt/snap_mysql || mount -o ro "/dev/$VG/$SNAP_MYSQL" /mnt/snap_mysql
rsync -aHAX /mnt/snap_mysql/ "$BACKDIR/mysql/"
umount /mnt/snap_mysql
lvremove -y "/dev/$VG/$SNAP_MYSQL"

echo "=== $(date -Is) backup done"

Замените ввод пароля на безопасный способ (локальный .my.cnf с правами 0600 или сокет/плагин), а также добавьте уведомления и выгрузку в удалённое хранилище.

Проверка и тест восстановления — обязательны

Бэкап без регулярной проверки — иллюзия безопасности. Делайте периодически пробный restore на отдельном стенде: распакуйте архивы, прогоните проверки целостности (для файлов — контрольные суммы, для MySQL — запуск с настройками по умолчанию и просмотр логов ошибок). Автоматизируйте минимальную проверку на уровне CI: подтверждение, что архив читается, структура каталогов соответствует ожиданиям, объёмы сопоставимы, а на тестовом экземпляре база успешно запускается.

Частые ошибки и как их избежать

  • Недооценили размер снапшота — он переполнился и стал невалидным. Увеличивайте с запасом, сокращайте окно жизни снапшота, переносите копирование на менее загруженные часы.
  • Забыли nouuid при монтировании XFS снапшота — ФС не примонтировалась. Добавьте опцию.
  • Долго держали FTWRL — приложения простаивали. Отработайте последовательность в тесте: «заморозка» должна занимать секунды.
  • Снимали снапшот без fsfreeze для чувствительных к метаданным сценариев — получили «грязное» состояние. Добавьте короткий freeze.
  • Восстанавливали MySQL, но забыли права/контексты — база не стартует. Проверьте владельца mysql:mysql и контексты безопасности.

Итоги

LVM snapshots — надёжный и быстрый способ организовать горячий backup на vds для файлов и баз данных. Ключевые элементы успеха: наличие свободного места в VG, краткая и безопасная «заморозка» (fsfreeze), минимальная блокировка в MySQL (FLUSH TABLES WITH READ LOCK), оперативное копирование и немедленное удаление снапшота. Регулярно проверяйте восстановление (restore) и контролируйте заполнение COW‑области — тогда бэкапы будут не только «сняты», но и реально пригодны в критический момент.

Поделиться статьей

Вам будет интересно

Fail2ban 2025: защита от SSH brute force и nginx basic auth, настройка bantime/ignoreip и отладка OpenAI Статья написана AI (GPT 5)

Fail2ban 2025: защита от SSH brute force и nginx basic auth, настройка bantime/ignoreip и отладка

Fail2ban в 2025 всё так же спасает от перебора паролей: читает логи, находит ошибки входа и банит IP через фаервол. В статье — нас ...
2FA для SSH и sudo на Linux: TOTP через pam_google_authenticator без лишней боли OpenAI Статья написана AI (GPT 5)

2FA для SSH и sudo на Linux: TOTP через pam_google_authenticator без лишней боли

Практический гайд по внедрению TOTP-2FA в Linux через pam_google_authenticator: установка, создание секрета, настройка PAM и OpenS ...
SLO-мониторинг с node_exporter и blackbox_exporter: latency, доступность и error budget OpenAI Статья написана AI (GPT 5)

SLO-мониторинг с node_exporter и blackbox_exporter: latency, доступность и error budget

Пошагово собираем SLO-мониторинг на Prometheus: node_exporter для диагностики хоста и blackbox_exporter для внешних проверок. Счит ...