Btrfs снапшоты в Linux: откат системы за секунды

Преимущества Btrfs и механизм снапшотов

Btrfs (B-tree File System) — файловая система нового поколения для Linux с поддержкой Copy-on-Write (COW). Снапшот в Btrfs — это мгновенный «слепок» состояния файловой системы, который создаётся за миллисекунды вне зависимости от объёма данных.

Как это работает: при создании снапшота Btrfs не копирует данные. Вместо этого снапшот и оригинал указывают на одни и те же блоки данных. Копирование происходит только при изменении — записывается новый блок, а снапшот продолжает ссылаться на старый. Это и есть Copy-on-Write.

Практические сценарии использования:

  • Откат после неудачного обновления системы
  • Снапшот перед установкой нового ПО
  • Ежечасные снапшоты рабочих данных
  • Замена традиционного бэкапа для быстрого восстановления
  • Тестирование конфигураций с возможностью мгновенного отката

Разметка диска и создание subvolumes

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

# Создание файловой системы Btrfs
mkfs.btrfs -L "rootfs" /dev/sda2

# Монтирование корня для создания subvolumes
mount /dev/sda2 /mnt

# Создание структуры subvolumes
btrfs subvolume create /mnt/@           # Корневая FS
btrfs subvolume create /mnt/@home       # Домашние каталоги
btrfs subvolume create /mnt/@var_log    # Логи (исключаем из снапшотов)
btrfs subvolume create /mnt/@snapshots  # Хранилище снапшотов

# Просмотр созданных subvolumes
btrfs subvolume list /mnt

umount /mnt

Разделение на subvolumes позволяет делать снапшот корня (@) без захвата логов и домашних каталогов, и наоборот.

Настройка /etc/fstab

Каждый subvolume монтируется отдельной записью в fstab:

# /etc/fstab
UUID=xxxx-xxxx  /              btrfs  subvol=@,defaults,noatime,compress=zstd:1  0  0
UUID=xxxx-xxxx  /home          btrfs  subvol=@home,defaults,noatime,compress=zstd:1  0  0
UUID=xxxx-xxxx  /var/log       btrfs  subvol=@var_log,defaults,noatime,compress=zstd:1  0  0
UUID=xxxx-xxxx  /.snapshots    btrfs  subvol=@snapshots,defaults,noatime  0  0
/dev/sda1        /boot/efi      vfat   defaults  0  1

Параметр compress=zstd:1 включает прозрачное сжатие, экономя 20-40% дискового пространства. Параметр noatime снижает количество операций записи.

Ручное создание и управление снапшотами

Базовые операции со снапшотами выполняются утилитой btrfs:

# Создание read-only снапшота корня
sudo btrfs subvolume snapshot -r / /.snapshots/root-$(date +%Y%m%d-%H%M%S)

# Создание read-write снапшота (для экспериментов)
sudo btrfs subvolume snapshot /home /.snapshots/home-before-migration

# Список всех снапшотов
sudo btrfs subvolume list -s /

# Информация о конкретном снапшоте
sudo btrfs subvolume show /.snapshots/root-20260408-120000

# Сравнение двух снапшотов (какие файлы изменились)
sudo btrfs send --no-data -p /.snapshots/snap1 /.snapshots/snap2 | btrfs receive --dump

# Удаление старого снапшота
sudo btrfs subvolume delete /.snapshots/root-20260401-120000

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

Оценка занимаемого места

Снапшоты разделяют данные с оригиналом, поэтому обычный du не покажет реальное потребление:

# Реальное использование дискового пространства
sudo btrfs filesystem usage /

# Эксклюзивное пространство каждого subvolume
sudo btrfs qgroup show / --raw

# Включение квот для точного учёта (может влиять на производительность)
sudo btrfs quota enable /
sudo btrfs qgroup show / -reF

Поле exclusive в qgroup показывает, сколько места освободится при удалении снапшота. Поле referenced — общий объём данных (включая разделяемые блоки).

Автоматизация снапшотов с помощью Snapper

Snapper — инструмент для автоматического управления снапшотами Btrfs с политиками ротации. Установка и настройка:

# Установка
sudo apt install snapper       # Debian/Ubuntu
sudo dnf install snapper       # Fedora/RHEL

# Создание конфигурации для корневого subvolume
sudo snapper -c root create-config /

# Создание конфигурации для /home
sudo snapper -c home create-config /home

# Просмотр конфигураций
snapper list-configs

Настройка политики ротации в файле /etc/snapper/configs/root:

# /etc/snapper/configs/root
SUBVOLUME="/"
FSYSTEM="btrfs"

# Автоматическое создание через systemd timer
TIMELINE_CREATE="yes"
TIMELINE_CLEANUP="yes"

# Политика хранения
TIMELINE_MIN_AGE="1800"       # минимальный возраст (сек)
TIMELINE_LIMIT_HOURLY="24"    # 24 часовых снапшота
TIMELINE_LIMIT_DAILY="7"      # 7 дневных
TIMELINE_LIMIT_WEEKLY="4"     # 4 недельных
TIMELINE_LIMIT_MONTHLY="6"    # 6 месячных
TIMELINE_LIMIT_YEARLY="1"     # 1 годовой

Snapper автоматически создаёт снапшоты каждый час и удаляет старые согласно политике. Для ручных операций:

# Создать снапшот вручную с описанием
sudo snapper -c root create --description "Before kernel update"

# Список всех снапшотов
sudo snapper -c root list

# Сравнение снапшотов
sudo snapper -c root diff 15..16

# Просмотр изменённых файлов
sudo snapper -c root status 15..16

Откат системы из снапшота

Основной сценарий — откат после неудачного обновления. Существует несколько подходов в зависимости от того, загружается система или нет.

Если система загружается (откат отдельных файлов):

# Восстановление конкретного файла из снапшота
sudo snapper -c root undochange 15..16 /etc/nginx/nginx.conf

# Откат всех изменений между снапшотами 15 и 16
sudo snapper -c root undochange 15..16

Полный откат корневого subvolume:

# Загрузитесь с Live USB или в recovery mode

# Монтируем корень Btrfs
mount /dev/sda2 /mnt

# Переименовываем сломанный корень
mv /mnt/@ /mnt/@broken

# Создаём read-write снапшот из рабочего снапшота
btrfs subvolume snapshot /mnt/@snapshots/root-20260407-120000 /mnt/@

# Перезагружаемся
reboot

# После проверки удаляем сломанный subvolume
sudo btrfs subvolume delete /.snapshots/@broken

Весь процесс занимает менее минуты, вне зависимости от объёма данных.

Загрузка из снапшота через GRUB

Пакет grub-btrfs автоматически добавляет снапшоты в меню загрузчика GRUB. При неудачном обновлении можно выбрать снапшот прямо при загрузке:

# Установка grub-btrfs
git clone https://github.com/Antynea/grub-btrfs.git
cd grub-btrfs
sudo make install

# Генерация записей GRUB
sudo grub-mkconfig -o /boot/grub/grub.cfg

# Включение автоматического обновления при создании снапшотов
sudo systemctl enable --now grub-btrfsd

Теперь в меню GRUB появится пункт «Btrfs snapshots» со списком всех снапшотов. Выбрав нужный, система загрузится в read-only режиме из этого снапшота. Для постоянного отката выполните процедуру переименования subvolume из предыдущего раздела.

Снапшоты перед обновлениями через APT hook

Настройте автоматическое создание снапшота перед каждым apt upgrade:

# /etc/apt/apt.conf.d/80snapper
DPkg::Pre-Invoke  { "snapper -c root create -d 'apt pre-upgrade' --type pre"; };
DPkg::Post-Invoke { "snapper -c root create -d 'apt post-upgrade' --type post"; };

Snapper создаст пару снапшотов (pre/post) для каждого обновления. Откат: snapper -c root undochange PRE_NUM..POST_NUM.

Отправка снапшотов на удалённый сервер

Btrfs поддерживает инкрементальную отправку снапшотов — передаются только изменённые блоки. Идеально для бэкапа на удалённый сервер:

# Первая полная отправка
sudo btrfs send /.snapshots/root-20260407-120000 | \
  ssh backup@remote "btrfs receive /backup/server01/"

# Инкрементальная отправка (только различия)
sudo btrfs send -p /.snapshots/root-20260407-120000 \
  /.snapshots/root-20260408-120000 | \
  ssh backup@remote "btrfs receive /backup/server01/"

# Скрипт автоматического инкрементального бэкапа
#!/bin/bash
LATEST=$(sudo btrfs subvolume list -s --sort=gen / | tail -1 | awk '{print $NF}')
PREVIOUS=$(sudo btrfs subvolume list -s --sort=gen / | tail -2 | head -1 | awk '{print $NF}')

if [ -n "$PREVIOUS" ]; then
  sudo btrfs send -p "/$PREVIOUS" "/$LATEST" | \
    ssh backup@remote "btrfs receive /backup/$(hostname)/"
else
  sudo btrfs send "/$LATEST" | \
    ssh backup@remote "btrfs receive /backup/$(hostname)/"
fi

При 100 ГБ данных и 2 ГБ ежедневных изменений инкрементальная отправка передаёт только 2 ГБ вместо полных 100 ГБ. Используйте сжатие через pipe: | zstd | ssh ... для дополнительной экономии канала.

Производительность и рекомендации

Btrfs с COW имеет свои особенности производительности. Следуйте рекомендациям:

  • Отключите COW для баз данных и виртуальных дисков: chattr +C /var/lib/mysql — атрибут устанавливается на пустой каталог до размещения файлов
  • Используйте compress=zstd:1 — минимальный уровень сжатия с максимальной скоростью, часто ускоряет I/O за счёт уменьшения объёма записи
  • Не включайте quota без необходимости — это замедляет операции со снапшотами на 10-30%
  • Регулярно выполняйте balance для оптимизации размещения данных:
# Балансировка (запускайте в периоды низкой нагрузки)
sudo btrfs balance start -dusage=50 -musage=50 /

# Проверка и исправление ошибок (scrub)
sudo btrfs scrub start /
sudo btrfs scrub status /

# Дефрагментация (полезна для SSD)
sudo btrfs filesystem defragment -r -czstd /

Для RAID-конфигураций используйте встроенный RAID Btrfs (mkfs.btrfs -d raid1 -m raid1 /dev/sda /dev/sdb) вместо mdadm — это обеспечит автоматическое исправление повреждённых блоков через контрольные суммы.

Часто задаваемые вопросы

Свежий снапшот занимает практически ноль места. Пространство расходуется только на изменённые блоки. Если за день изменяется 1% данных от 100 ГБ раздела, 24 часовых снапшота займут максимум 24 ГБ (на практике меньше из-за перекрытий). Рекомендуется оставлять 20-30% свободного места на разделе.

Нет. Снапшоты хранятся на том же диске, что и оригинал. При выходе диска из строя теряются и данные, и снапшоты. Используйте btrfs send для отправки снапшотов на отдельный носитель или сервер — это будет полноценным бэкапом.

Btrfs в конфигурации single или RAID1 считается стабильной и используется в SUSE Linux Enterprise, Facebook и Synology NAS. Избегайте RAID5/6 на Btrfs — эти режимы до сих пор имеют проблемы. Для RAID5/6 используйте mdadm поверх Btrfs.

Btrfs поддерживает конвертацию на месте: btrfs-convert /dev/sda2. Команда создаёт Btrfs поверх ext4, сохраняя образ старой FS для отката. Однако для продуктива рекомендуется чистая установка с правильной структурой subvolumes — конвертация не создаёт subvolumes автоматически.

Нужна помощь с настройкой?

Специалисты АйТи Фреш помогут с внедрением и настройкой — 15+ лет опыта, обслуживание от 15 000 ₽/мес

📞 Связаться с нами
#Btrfs#снапшоты Linux#откат системы#Snapper#subvolume#Btrfs snapshot#резервное копирование Linux#файловая система Btrfs
Комментарии 0

Оставить комментарий

загрузка...