btrfs снапшоты и subvolume на Ubuntu: откат системы за 5 секунд
btrfs делает снапшот тома за миллисекунды и без расхода места — это copy-on-write слепок, в который можно «вернуться» после неудачного `apt upgrade`. Разбираем разницу с ext4, как готовить разметку под subvolume, снимать снимки, откатываться и чистить старые на Ubuntu 24.04 LTS.
btrfs снапшот и subvolume: рабочий гайд по откату системы
btrfs делает снапшот тома за миллисекунды и без расхода места — это copy-on-write слепок, в который можно «вернуться» после неудачного apt upgrade. Разбираем разницу с ext4, как готовить разметку под subvolume, снимать снимки, откатываться и чистить старые на Ubuntu 24.04 LTS.
Сравниваем btrfs и ext4
Обе файловые системы стабильно работают в продакшне Ubuntu, но решают разные задачи.
Что делает ext4 хорошо:
- Предсказуемая производительность под почти любую нагрузку.
- Минимум сюрпризов: 15+ лет шлифовки, рабочие инструменты восстановления (
fsck.ext4,e2fsck). - Меньше CPU-нагрузка и потребление RAM на тех же объёмах.
Что btrfs даёт сверху:
- Снапшоты за миллисекунды — copy-on-write, не копирует данные физически.
- Subvolume — независимые «деревья» внутри одного раздела, каждое можно снапшотить и монтировать отдельно.
- Встроенные RAID 0/1/10, проверка целостности через checksums, прозрачное сжатие (
zstd). - Send/receive — инкрементальная репликация снапшота на другую машину.
Когда брать btrfs:
- Сервер, на котором вы катите
apt upgradeи хотите безопасный откат. - Машина для разработки, где важна возможность «вернуть рабочее состояние».
- Хранилище с дедупликацией и сжатием логов/бэкапов.
Когда оставить ext4:
- Базы данных с высоким write-load (PostgreSQL, MySQL): COW добавляет фрагментацию, и общее правило —
chattr +Cили вообще ext4 для томов БД. - Сервер, где снапшоты не нужны, а нужна максимальная стабильность с минимумом администрирования.
- Очень слабое железо: btrfs прожорливее по RAM и CPU при метаданных.
Резюме: для системного раздела Ubuntu-сервера btrfs выигрывает за счёт снапшотов; для томов с базами данных оставайтесь на ext4 (или используйте btrfs с nodatacow).
Готовим btrfs на Ubuntu 24.04
При установке Ubuntu Server 24.04 в инсталляторе можно выбрать btrfs для корневого раздела — он создаст subvolume @ для / и @home для /home. Это рекомендованная разметка: позволяет снапшотить систему без захвата пользовательских данных.
Если ставите вручную или добавляете btrfs-том к существующей системе:
sudo apt install -y btrfs-progs
sudo mkfs.btrfs -L data /dev/sdb1
sudo mkdir /mnt/data
sudo mount /dev/sdb1 /mnt/data
В /etc/fstab:
UUID=<uuid-из-blkid> /mnt/data btrfs defaults,compress=zstd:3,noatime 0 0
Что важно в опциях:
compress=zstd:3— прозрачное сжатие, уровень 3. Дешёвый CPU-trade за 30–50% экономии места на текстовых данных и логах. Для уже сжатых данных (mp4, jpg) btrfs сам пропустит сжатие.noatime— не обновляет время доступа при чтении. Снижает write-нагрузку, экономит снапшотам место (иначе каждое чтение создаёт «изменение»).subvol=@— указать конкретный subvolume для монтирования (нужно для системного раздела с разметкой по subvolume).
Создаём subvolume
Subvolume — это «папка с правами файловой системы»: её можно отдельно монтировать, отдельно снапшотить, переименовать или удалить целиком за миллисекунды (а не rm -rf миллион файлов).
sudo btrfs subvolume create /mnt/data/projects
sudo btrfs subvolume create /mnt/data/backups
sudo btrfs subvolume list /mnt/data
Вывод list покажет ID, путь и parent — используется для снапшотов и откатов.
Ключевые правила subvolume:
- Внутри subvolume могут жить вложенные subvolume — но при снапшоте родителя вложенные не попадают в снапшот, остаются как пустые точки. Это сознательный дизайн btrfs: разделение
@и@homeименно для этого. - Удалить subvolume —
sudo btrfs subvolume delete /mnt/data/projects. На проде это не делается случайно черезrm -rf— у subvolume другая семантика. - ID subvolume стабильный, путь можно переименовать через
mv.
Делаем снапшот
Снапшот btrfs — это новый subvolume, который изначально полностью совпадает с исходным, но дальше каждая запись в любой из них копирует только изменённые блоки (copy-on-write). Поэтому свежий снапшот не занимает места.
Снимаем read-only-снапшот (рекомендуется — гарантирует, что внутри ничего не подменят):
sudo btrfs subvolume snapshot -r /mnt/data/projects \
/mnt/data/.snapshots/projects-$(date +%Y%m%d-%H%M)
Без -r получится read-write-снапшот — можно работать в нём как в обычном subvolume.
Системный снапшот корня перед apt upgrade (если корень на btrfs с layout @):
sudo btrfs subvolume snapshot / /.snapshots/root-pre-upgrade-$(date +%Y%m%d)
sudo apt update && sudo apt upgrade -y
Если после апгрейда сломалась загрузка или критический сервис — у вас есть точка возврата.
Откатываем систему из снапшота
Идея отката: переименовать сломанный subvolume в архив, переименовать снапшот на его место, перезагрузиться.
sudo mv /.snapshots/root-broken /.snapshots/root-broken-$(date +%Y%m%d)
sudo mv / /broken-rootfs # это упрощённая схема, см. ниже
sudo mv /.snapshots/root-pre-upgrade-20260504 /
В реальности на корневом разделе работать с / напрямую нельзя — нужно бутаться с live-USB или из initramfs-shell, монтировать btrfs-том без subvol= и переименовывать subvolume через btrfs subvolume. Поэтому продакшен-сценарий выглядит так:
Загрузиться в initramfs (выбрать в GRUB recovery mode или с live-USB).
Смонтировать корневой btrfs без subvolume-флага:
sudo mount /dev/nvme0n1p2 /mnt.Переименовать сломанный
@и поставить снапшот:sudo mv /mnt/@ /mnt/@.broken sudo btrfs subvolume snapshot /mnt/.snapshots/root-pre-upgrade-20260504 /mnt/@Размонтировать, перезагрузиться.
Менее травматичная альтернатива — snapper rollback (см. ниже): он автоматизирует переименования и работает прямо из загруженной системы при условии, что у вас разметка по schema snapper.
Автоматизируем снапшоты
Вручную делать снапшот перед каждым apt — неустойчиво. Стандартный инструмент Ubuntu — snapper:
sudo apt install -y snapper
sudo snapper -c root create-config /
sudo snapper -c home create-config /home
Snapper создаёт конфиги в /etc/snapper/configs/ и автоматически снимает снапшоты по таймеру. Включите systemd-таймеры:
sudo systemctl enable --now snapper-timeline.timer
sudo systemctl enable --now snapper-cleanup.timer
timeline.timer — снапшоты по расписанию (час/день/неделя/месяц). cleanup.timer — удаляет старые по политике в конфиге (по умолчанию хранит ~10 hourly, 10 daily, 10 weekly).
Кроме того, в Ubuntu есть apt-btrfs-snapshot — хук, делающий снапшот корня перед apt install/upgrade/remove. Полезный страховочный слой.
Если snapper кажется тяжёлым, минимальная альтернатива — свой systemd-таймер с однострочником:
# /etc/systemd/system/btrfs-snapshot-data.service
[Unit]
Description=Hourly snapshot of /mnt/data
[Service]
Type=oneshot
ExecStart=/usr/bin/btrfs subvolume snapshot -r /mnt/data /mnt/data/.snapshots/auto-%i
# /etc/systemd/system/btrfs-snapshot-data.timer
[Unit]
Description=Hourly btrfs snapshots
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
Включаем: sudo systemctl enable --now btrfs-snapshot-data.timer.
Чистим старые снапшоты
Свежий снапшот занимает 0 байт, но со временем расхождение между ним и текущим состоянием растёт. Если не чистить — раздел заполнится. Считаем сколько весят снапшоты:
sudo btrfs filesystem usage /mnt/data
sudo btrfs subvolume list -t /mnt/data
Удаляем по одному:
sudo btrfs subvolume delete /mnt/data/.snapshots/projects-20260301-0900
Удалять можно безопасно: данные уйдут только когда они не нужны другим снапшотам и текущим subvolume. Для массовой чистки старых snapper-снапшотов:
sudo snapper -c root list
sudo snapper -c root delete 100..150 # удалить диапазон
Если место уже кончилось и delete не помогает — стоит запустить btrfs balance:
sudo btrfs balance start -dusage=50 /mnt/data
Это переупаковывает блоки, у которых заполнено меньше 50%, и возвращает свободное место в общий пул.
Частые вопросы
Что лучше btrfs или ext4
Зависит от задачи. Для системного раздела сервера, где важны откаты после apt upgrade, безопаснее btrfs — снапшот делается за миллисекунды и не требует места. Для томов с базами данных и максимальной стабильностью лучше ext4: меньше фрагментация при write-heavy нагрузке и более отполированные инструменты восстановления.
Сколько места занимает снапшот btrfs
Свежий снапшот занимает практически 0 байт — он ссылается на те же блоки, что и исходный subvolume. Расход растёт по мере того, как в исходнике или снапшоте идёт запись: copy-on-write копирует только изменённые блоки. Поэтому хранить десятки снапшотов на стабильной системе дёшево, но при активных изменениях место расходуется быстро.
Чем subvolume отличается от обычной директории
Обычная директория — это просто узел в дереве файловой системы. Subvolume — независимое поддерево внутри btrfs-тома, у которого свой ID, его можно отдельно монтировать, снапшотить, переименовывать и удалять одной операцией. При снапшоте родительского subvolume вложенные subvolume в снапшот не попадают — это позволяет, например, не захватывать /home при снимке /.
Как откатить систему из снапшота btrfs
Самый надёжный путь — загрузиться в recovery-режим или с live-USB, смонтировать btrfs-том без subvolume-флага, переименовать сломанный @ в @.broken и сделать btrfs subvolume snapshot из своего pre-upgrade-снапшота на место @. После перезагрузки система загрузится в состояние снапшота. Snapper автоматизирует это через snapper rollback, если у вас совместимая разметка.
Можно ли использовать btrfs для базы данных PostgreSQL
Можно, но с оговорками. Copy-on-write на write-heavy нагрузке вызывает фрагментацию, и производительность БД падает. Стандартная практика — отключать COW для каталога с данными БД через chattr +C /var/lib/postgresql (только для пустого каталога, до начала работы) или просто держать том БД на ext4. Снапшоты при этом всё равно работают, но будут тяжелее.
Зачем нужно btrfs balance
Btrfs хранит данные в блок-группах размером ~1 ГБ. Со временем после удалений блок-группы заполняются неравномерно — половина блок-группы пустая, но место не возвращается в общий пул. btrfs balance start -dusage=50 находит такие полупустые блок-группы и переупаковывает их. Запускать стоит периодически, особенно после массовых удалений снапшотов.
Что запомнить
- btrfs выигрывает у ext4 там, где нужны мгновенные снапшоты и откаты; ext4 — там, где нужна максимальная стабильность и предсказуемая производительность под тяжёлый write-load.
- На Ubuntu при установке выбирайте btrfs с разметкой
@и@home— это даёт чистую базу для системных снапшотов без захвата пользовательских данных. - Снапшот делайте перед каждым серьёзным
apt upgrade. Команда —btrfs subvolume snapshot -r / /.snapshots/root-pre-upgrade-<date>. - Чистите старые снапшоты — иначе раздел заполнится. Для автоматики —
snapperсtimeline.timerиcleanup.timer. - Откат проще делать через snapper или из recovery-режима, не пытайтесь переименовать
/на работающей системе.