· 15 мин чтения

Btrfs-снапшоты и откат Linux-сервера: полноценный аналог System Restore

Меня зовут Семёнов Евгений Сергеевич, я директор АйТи Фреш. За 15+ лет работы с Linux-серверами одна из самых частых проблем — это неудачное обновление пакетов, после которого сервис перестаёт работать, а инженер сидит и судорожно вспоминает, какие именно библиотеки нужно откатить. Btrfs-снапшоты с snapper решают это элегантно: три команды — и система вернулась в состояние «до update». У меня на практике именно такая схема спасает серверы клиентов от крупных простоев.

Почему именно Btrfs, а не LVM-снапшоты

LVM-снапшоты существуют с начала 2000-х, и они работают, но плохо масштабируются. Каждый LVM snapshot требует выделения места заранее, и если вы сделали пять снимков за день, их хранение становится дорогим удовольствием. Плюс LVM snapshot блокирующий — запись в оригинальный том замедляется пропорционально количеству снимков.

Btrfs использует copy-on-write на уровне файловой системы. Снапшот — это просто новая ссылка на те же блоки данных. Создаётся мгновенно, занимает 0 байт на момент создания, растёт только по мере изменения файлов. На сервере с 500 ГБ данных и 60 снапшотами я обычно вижу оверхед 20-40 ГБ — в зависимости от того, насколько активно меняются файлы.

Разметка диска под Btrfs с субтомами

Правильная схема разметки — половина успеха. Я всегда использую раздельные субтомa для корня, /home и /var/log. Это даёт три вещи: откатить систему, не затронув пользовательские данные; исключить /var/log из снапшотов, чтобы не раздувать их; точный контроль над политикой хранения для каждой категории.

# На чистом SSD (допустим /dev/nvme0n1p2 — корневой раздел)
mkfs.btrfs -L system /dev/nvme0n1p2
mount /dev/nvme0n1p2 /mnt

# Создаём субтомa
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@var_log
btrfs subvolume create /mnt/@snapshots

# Отдельно для кеша и кэш-директорий, которые не нужны в снапшотах
btrfs subvolume create /mnt/@var_cache
btrfs subvolume create /mnt/@tmp

В /etc/fstab каждый субтом монтируется отдельной строкой с опцией subvol=@.... Важно: опция compress=zstd:3 даёт бесплатное сжатие 1.5-2x на текстовых данных, noatime убирает лишние записи времени доступа.

UUID=xxx /              btrfs subvol=@,compress=zstd:3,noatime,ssd 0 0
UUID=xxx /home          btrfs subvol=@home,compress=zstd:3,noatime,ssd 0 0
UUID=xxx /var/log       btrfs subvol=@var_log,compress=zstd:3,noatime,ssd 0 0
UUID=xxx /.snapshots    btrfs subvol=@snapshots,noatime,ssd 0 0
UUID=xxx /var/cache     btrfs subvol=@var_cache,noatime,ssd 0 0

Установка и настройка snapper

Snapper — это демон, который управляет снапшотами по расписанию и по событиям. Автоматически делает pre/post снимки при запусках apt/dnf через хуки пакетного менеджера.

# Ubuntu/Debian
sudo apt install snapper

# Создаём конфиг для корня (важно: root subvolume должен быть Btrfs)
sudo snapper -c root create-config /
sudo snapper -c home create-config /home

# Смотрим список
sudo snapper -c root list-configs

Редактируем /etc/snapper/configs/root. Типовые параметры, которые я всегда правлю:

TIMELINE_CREATE="yes"
TIMELINE_CLEANUP="yes"
TIMELINE_LIMIT_HOURLY="10"
TIMELINE_LIMIT_DAILY="10"
TIMELINE_LIMIT_WEEKLY="8"
TIMELINE_LIMIT_MONTHLY="6"
TIMELINE_LIMIT_YEARLY="0"

NUMBER_CLEANUP="yes"
NUMBER_LIMIT="50"
NUMBER_LIMIT_IMPORTANT="20"

Хуки APT для автоматических снимков

Ключевой сценарий: перед apt upgrade делаем pre-снапшот, после — post. Если обновление сломало систему, откатываемся на pre. В Debian/Ubuntu для этого есть пакет snapper-gui и btrfs-progs, плюс скрипт в APT-хуках.

sudo apt install apt-btrfs-snapshot

Теперь каждая операция apt создаёт снимок автоматически. В Fedora/openSUSE snapper из коробки интегрирован с dnf/zypper.

Смотрим список снимков:

sudo snapper -c root list

 # | Type   | Pre # | Date                     | User | Cleanup | Description
---+--------+-------+--------------------------+------+---------+-----------------
 0 | single |       |                          | root |         | current
42 | pre    |       | Wed Jun 04 08:15:12 2025 | root | number  | apt
43 | post   | 42    | Wed Jun 04 08:17:44 2025 | root | number  |
44 | single |       | Wed Jun 04 09:00:02 2025 | root | timeline| timeline

Откат после неудачного обновления

Допустим, после обновления сервер потерял сеть или сервис перестал стартовать. Алгоритм отката:

# Смотрим недавние pre-снапшоты
sudo snapper -c root list --type pre-post | tail

# Откатываемся на состояние ДО снапшота 42
sudo snapper -c root rollback 42

# Либо через diff смотрим, что изменилось
sudo snapper -c root status 42..43

# Для файлового отката отдельных файлов
sudo snapper -c root -v undochange 42..0 /etc/nginx/nginx.conf

Команда rollback создаёт новый субтом из указанного снапшота и делает его default. После перезагрузки сервер грузится с состояния на момент pre-снапшота. Важно: изменения в /home и /var/log не затрагиваются (если они отдельные субтома), то есть пользовательские данные и логи сохраняются.

Что именно восстанавливается — сравнение

СубтомВосстанавливается при rollbackХранит снапшоты
@ (корень)Да, полностьюДа
@homeНетОтдельно (home-конфиг snapper)
@var_logНетНет (исключён)
@var_cacheНетНет
@tmpНетНет
@snapshotsОсобый — хранит сами снимкиНет

Восстановление отдельных файлов

Не всегда нужен полный откат. Часто требуется вытащить один файл из вчерашнего состояния — например, испорченный конфиг nginx. Каждый снапшот монтируется в /.snapshots/N/snapshot, откуда можно обычным cp скопировать что нужно:

# Список снапшотов
ls /.snapshots/

# Достаём конфиг из снапшота 44
sudo cp /.snapshots/44/snapshot/etc/nginx/sites-available/example.conf \
        /etc/nginx/sites-available/example.conf

sudo systemctl reload nginx

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

Btrfs поддерживает btrfs send/receive — инкрементальную репликацию снимков по SSH. Это мощная замена rsync для крупных FS.

# Первый (полный) бэкап
sudo btrfs send /.snapshots/100/snapshot | \
  ssh backup@storage "btrfs receive /backup/server1/"

# Инкрементальный
sudo btrfs send -p /.snapshots/100/snapshot /.snapshots/101/snapshot | \
  ssh backup@storage "btrfs receive /backup/server1/"

У нас на практике такая схема работает на клиентских серверах с еженощной репликацией на NAS в дата-центре МТС. Передача 500 ГБ базы данных инкрементально занимает 2-4 минуты, потому что отправляются только изменившиеся блоки.

Кейс: откат после обновления PHP

В апреле 2025 один из клиентов — интернет-магазин мебели на Bitrix — попросил нас обновить PHP с 8.1 на 8.2. После apt-upgrade на staging-сервере несколько кастомных расширений Bitrix перестали работать, сайт возвращал 500-е ошибки. Обычно в такой ситуации инженер тратит 1-2 часа на восстановление вручную: apt-history, удаление новых пакетов, установка старых версий.

У нас snapper сделал pre-snapshot автоматически перед обновлением. Команда snapper -c root rollback 187 и перезагрузка заняли три минуты. Сайт снова работал на PHP 8.1. Дальше мы на тест-контуре развернули обновление правильно — с предварительной подготовкой модулей — и повторили его в проде. Сервер — Dell PowerEdge R640 с Xeon Silver 4210, 64 ГБ RAM, NVMe RAID-1, стоит в дата-центре МТС.

Грабли, о которых нужно знать

У Btrfs есть особенности, на которых легко обжечься:

Настроим Btrfs + snapper на ваших серверах

Развернём Btrfs с правильной разметкой, snapper с автоснимками и репликацией на удалённое хранилище. Обучим администратора делать откаты и восстанавливать файлы. Работаем с Ubuntu LTS, Debian, openSUSE, Rocky Linux.

Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш

FAQ — частые вопросы по Btrfs

Btrfs или ZFS — что выбрать в 2025?
ZFS стабильнее для нагруженного storage. Btrfs удобнее для rolling-release с откатом через snapper. Оба готовы к проду в своих нишах.
Можно ли использовать Btrfs на RAID-5/6?
Не рекомендуется из-за write hole. Используйте mdadm RAID-10 или hardware RAID как основу, а Btrfs поверх.
Как snapper делает снапшот?
Создаёт Btrfs subvolume snapshot через CoW — мгновенно и без дублирования данных.
Что если откат сломал загрузку?
Грузимся с live-USB, btrfs subvolume set-default на рабочий снимок, обновляем GRUB.
Сколько снапшотов хранить?
Стандартная политика: 10 hourly + 10 daily + 8 weekly + 6 monthly. Корректируйте под свободное место на диске.

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.