Btrfs-снапшоты и откат Linux-сервера: полноценный аналог System Restore
Привет! Семёнов Евгений Сергеевич, директор ITFresh. Знаете, уже больше 15 лет я работаю с Linux-серверами, и одна проблема всегда выводила из себя: неудачное обновление пакетов. Сервис буквально падает, а наш инженер сидит, весь в мыле, лихорадочно пытаясь вспомнить, какие же библиотеки нужно было откатывать. Вот тут Btrfs-снапшоты в паре со Snapper — настоящее спасение! Три команды — и система снова работает, как часы, ровно в том состоянии, что было до злосчастного апдейта. Поверьте моему опыту: эта схема реально спасает серверы клиентов от часов простоя.
Почему именно Btrfs, а не LVM-снапшоты
LVM-снапшоты, конечно, появились давно, в начале двухтысячных, и в целом работают. Но вот с масштабируемостью у них, скажем прямо, совсем не фонтан. Каждый LVM snapshot требует заранее выделенного под него места. Представьте: вы сделали всего пять снимков за день — и вот их хранение уже влетает в копеечку. И это не единственная загвоздка: LVM snapshot — блокирующий. Это значит, что любая запись в ваш основной том будет тормозиться. Чем больше таких снимков, тем сильнее вы почувствуете это замедление.
Btrfs же работает кардинально по-другому! Она задействует механизм copy-on-write прямо на уровне файловой системы. Что это даёт? Снапшот в Btrfs — это просто новая ссылка на те же самые блоки данных. Создаётся он буквально мгновенно, и, что самое крутое, в момент появления занимает ровно 0 байт! Расти снапшот начинает, только когда меняются файлы. Например, на одном из наших серверов, где хранятся 500 ГБ данных и около 60 снапшотов, мы обычно видим оверхед всего в 20-40 ГБ. Конечно, тут всё сильно зависит от того, насколько активно файлы меняются.
Разметка диска под Btrfs с субтомами
Грамотная схема разметки — это уже полдела, если не больше! Мы всегда разбиваем систему на отдельные субтома: для корня, для /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
Благодаря Snapper, каждая ваша операция с 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/"
У нас в ITFresh эта схема прекрасно работает на множестве клиентских серверов. Мы даже настраиваем еженощную репликацию на NAS в дата-центре МТС. Например, передача инкрементальной части базы данных объемом 500 ГБ занимает всего 2-4 минуты. Почему так быстро? Потому что отправляются только изменившиеся блоки.
Кейс: откат после обновления PHP
Помните апрель 2025-го? К нам тогда обратился один из наших клиентов – у них крупный интернет-магазин мебели на Bitrix. Их просьба была простая: обновить PHP с 8.1 до 8.2. Мы, как положено, начали со staging-сервера, запустили apt-upgrade, и тут началось… Несколько кастомных расширений Bitrix напрочь отказались работать, а сам сайт стал сыпать 500-ми ошибками. В обычной ситуации наш инженер, наверное, потратил бы час, а то и два, на ручное восстановление. А это, согласитесь, то ещё удовольствие: копаться в 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 есть свои особенности, на которых, не зная, очень легко обжечься:
- RAID-5/6 в Btrfs нестабилен. Не используйте в проде. Для избыточности — mdadm RAID-10 или RAID-1 под Btrfs.
- qgroup замедляет запись. Не включайте квоты субтомов на нагруженных серверах — производительность падает в 2-3 раза.
- Балансировка нужна раз в квартал.
btrfs balance start -dusage=50 /— освобождает фрагментированные экстенты. - Сжатие zstd не лечит заполненность. Файловая система всё равно должна видеть свободные блоки.
- Докер любит раздувать субтома. Для Docker используйте отдельный субтом и overlay2, а не btrfs storage driver.
Настроим 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. Корректируйте под свободное место на диске.
