df -h на btrfs показывает картину, которая не совпадает с реальностью: суммарный размер подмонтированных точек, а не фактическое занятое место. Когда на системе со снапшотами «заканчивается место», первым делом нужно понять, что именно кончилось — данные, метаданные или лимит снапшотов. Разберём, как читать btrfs-статистику, кто съедает место и что делать, когда система пишет ENOSPC.
df считает по точкам монтирования. Каждый подтом btrfs, смонтированный отдельно — @, @home, @snapshots — выглядит как самостоятельный раздел со своим размером. Но физически все они живут в одном пуле, и df показывает для каждой точки один и тот же объём целиком. Сумма строк в выводе может в разы превышать реальный размер диска, а занятость каждой точки — это не «сколько занимает подтом», а «сколько занято во всей файловой системе».
Плюс btrfs умеет сжимать данные и делиться экстентами между подтомами и снапшотами. Один и тот же блок может быть виден из десяти снапшотов, но занимать место один раз. df про это ничего не знает: он складывает видимые размеры, а не уникальные.
Поэтому первое правило мониторинга: df -h годится для грубой оценки «диск вообще полный или нет», а для ответа «сколько реально занято и кем» нужны инструменты btrfs.
Три команды закрывают три вопроса: сколько выделено, сколько занято и на каком устройстве всё живёт.
btrfs filesystem df / — распределение по типам:
btrfs filesystem df /
Вывод показывает три строки — Data, Metadata, System — с двумя числами в каждой: total (сколько места выделено под этот тип) и used (сколько реально занято). Разница между ними — запас, который btrfs держит под будущие записи. Если used по Data приближается к total, файловая система начнёт выделять новые блоки, и тут может упереться в нехватку места.
btrfs filesystem usage / — полный отчёт:
btrfs filesystem usage /
Здесь уже видно устройство, общий размер, занятое и свободное место, а также разбивка по типам с процентами. Это главная команда для еженедельной проверки: один взгляд — и понятно, сколько осталось и куда уходит.
btrfs filesystem show / — сводка по устройству:
btrfs filesystem show /
Показывает UUID, размер устройства и общее занятое место. Полезна, когда на машине несколько дисков и нужно понять, на каком из них живёт корень.
На системе со снапшотами три главных пожирателя места.
Снапшоты. Каждый снапшот сам по себе почти ничего не весит — он ссылается на существующие данные. Место растёт, когда файлы меняются: старые версии остаются в снапшотах, новые занимают новые блоки. Чем больше обновлений и изменений, тем быстрее растёт разница между «местом в подтоме» и «местом на диске».
Посмотреть список снапшотов:
btrfs subvolume list -s /
А сколько реально занимает каждый подтом — через btrfs filesystem du:
btrfs filesystem du / --exclude /proc --exclude /sys
du покажет размер каждого подтома с учётом общих экстентов. Для снапшотов snapper удобнее его же инструмент:
snapper list
Здесь видно даты и типы снапшотов — по ним легко понять, какие точки можно удалить без сожаления.
Кэш pacman. Пакеты после установки остаются в /var/cache/pacman/pkg и копятся годами. На btrfs это двойная проблема: кэш лежит в подтоме @, и его рост раздувает разницу между снапшотами. Чистка разобрана в статье про paccache, а здесь запомни главное: paccache -rk2 оставляет две последние версии каждого пакета и освобождает гигабайты.
Журналы. journalctl по умолчанию ограничен размером, но на десктопе с частыми обновлениями журнал легко разрастается. Проверить:
journalctl --disk-usage
Если журнал съел больше пары сотен мегабайт — journalctl --vacuum-size=200M вернёт его к разумным размерам.
Ключевое отличие btrfs от классических файловых систем: снапшот при создании не копирует данные. Он фиксирует состояние подтома, а сами блоки остаются общими. Место начинает расти только при изменении файлов — старые версии остаются «жить» в снапшотах.
Отсюда два следствия.
Первое: df -h / может показывать почти полный диск, даже если в самом подтоме @ файлов немного. Всё занятое место — это исторические версии файлов, которые держат снапшоты. Удалил снапшоты — место вернулось, хотя в подтоме ничего не менялось.
Второе: «нет места» наступает не тогда, когда «заполнился подтом», а когда заполнился весь пул. btrfs не умеет сказать «подтом переполнен» — он упирается в общий объём устройства. Поэтому на системе со снапшотами следить нужно за btrfs filesystem usage /, а не за df по конкретной точке.
Главный симптом — ошибка No space left on device (ENOSPC). На btrfs она коварная: может появиться при свободных данных, если кончились метаданные. Metadata — это структуры, описывающие файлы и экстенты; при большом количестве мелких файлов и снапшотов они растут быстрее данных. btrfs filesystem df / покажет: Data ещё свободна, а Metadata упёрлась в потолок.
Второй признак — ошибки в чистке снапшотов. snapper cleanup падает с ENOSPC, когда не может записать изменения в метаданные. При этом снапшоты продолжают копиться, и ситуация ухудшается.
Что делать, по порядку:
sudo snapper -c root delete 1..5
Сначала snapper list, чтобы не удалить свежие точки. Освободившиеся блоки btrfs вернёт не сразу — но место для метаданных появится.
sudo paccache -rk2
sudo btrfs balance start -dusage=50 /
Балансировка перераспределяет блоки и возвращает пустые экстенты в пул. -dusage=50 трогает только блоки данных, заполненные меньше чем наполовину — это безопасно и быстро. Если не помогло, попробуй -dusage=70, потом -musage=50 для метаданных. Полная балансировка без фильтров на большом диске может занять часы — не запускай её без необходимости.
После балансировки снова btrfs filesystem usage / — картина должна измениться в сторону свободного места.
Три привычки, которые не дают месту закончиться.
Лимиты snapper. В /etc/snapper/configs/root стоят TIMELINE_LIMIT_* — сколько снапшотов каждого уровня хранить. Если место уходит быстро, уменьши лимиты: например, TIMELINE_LIMIT_HOURLY="3" вместо 5. Настройка подсистемы разобрана в гайде про снапшоты с первого дня, здесь важно одно: лимиты — это и есть главный предохранитель.
Мониторинг. Щедро на алерты: лучше получить лишнее предупреждение, чем однажды не загрузиться. Простой вариант — cron-задача, которая раз в день гоняет btrfs filesystem usage / и пишет в лог, или скрипт, который шлёт уведомление, когда занято больше 85%. Порог выбирай с запасом: на btrfs последние проценты уходят быстро, потому что снапшоты продолжают расти даже при «почти полном» диске.
Привычка. Раз в неделю — btrfs filesystem usage / и взгляд на snapper list. Пять секунд, которые показывают тренд: если занятое место растёт быстрее, чем обычно, значит, что-то изменилось — новые лимиты, разросшийся журнал или кэш. Поймал на ранней стадии — починил за минуту.
Потому что df суммирует подмонтированные точки, а подтомы btrfs делят один пул. Каждая точка показывает весь объём файловой системы, и сумма строк превышает реальный размер. Для реальной картины используй btrfs filesystem usage /.
Скорее всего, кончились метаданные. Проверь btrfs filesystem df /: если Metadata used близко к total — удали лишние снапшоты и запусти btrfs balance start -musage=50 /.
Место занимают не сами снапшоты, а разница между текущим состоянием и историей. Если файлы активно менялись, старые версии лежат в снапшотах и держат место. Плюс кэш pacman и журналы — проверь их в первую очередь.
Только по необходимости. Если btrfs filesystem usage / показывает большой разрыв между total и used по Data — балансировка вернёт место. Регулярная балансировка без причины только нагружает диск.
Мониторинг места на btrfs — это три команды (btrfs filesystem df, usage, show), понимание, что снапшоты едят место только при изменении файлов, и привычка смотреть на тренд раз в неделю. df -h оставь для грубой оценки, а решения принимай по данным btrfs. ENOSPC на такой системе почти всегда лечится чисткой снапшотов и балансировкой — главное, заметить проблему до того, как она превратится в невозможность записать обновление.
Задай вопрос в чате — отвечаем быстро, по делу и без воды.
Комментарии