BTRFS и свободное место
Я нахожу BTRFS довольной интересным видом ФС. Но одна из проблем, которая прямо преследует новичков в BTRFS – сложность определения свободного пространства в разделе. В простейшем случае можно воспользоваться df, как и для других ФС.
$ df -h /home/
Filesystem Size Used Avail Use% Mounted on
/dev/nvme3n1p1 7,2T 6,9T 331G 96% /home
Кажется, что всё должно быть просто и у нас есть 331G свободного места. Но если спросить человека, который наработал опыт с BTRFS, он вам однозначно скажет, что не ему недостаточно вывода df для определения, есть ли здесь свободное место. Нюанс в том, как именно BTRFS распределяет свободное место и как это увидеть.
Где метрики?
У BTRFS есть команда filesystem usage для получения метрик по ФС. Флажок -T выведет данные в красивой табличной форме, удобной для чтения. Попробуем.
Да, тут данных значительно больше. Не пугайтесь, сейчас всё разберём по-порядку.
Как считается Free (estimated)
Первая метрика – Device size, общий объём раздела. Device size состоит из Device allocated (выделенное место) и Device unallocated (не выделенное). Device unallocated – гарантированно свободное на данный момент место.
По мере заполнения раздела, BTRFS будет выделять место из Device unallocated чанками (блоками данных). Чанки делятся по видам содержимого: для данных Data, метаданных Metadata и общесистемных блоков с информацией System. Детальную информацию по выделенной (и даже не выделенной) памяти видно в таблице снизу. Строчка Total подскажет общий объём выделенного места в зависимости от типа.
Выделение чанка не значит, что он сразу будет полностью заполнен. Например, если выделен чанк на 1G для данных и туда был записан только один файл на 4K, то там будет ещё много свободного места. Если же чанк освободится полностью, то он будет де-аллоцирован, а его объём будет возвращён в пул Device unallocated. Строчка Used в таблице подскажет объём занятого пространства по типам.
Если взять чанки всех 3-х типов и сложить, сколько места там занято, то получим общее значение Used из списка сверху. При ручном сложении нужно особо уделять внимание профилям. У меня Metadata и System имеют профиль RAID1. Объём данных там нужно умножать на 2. Если профиль single, то просто складываем.
И если теперь из общего Device size вычесть сумму Used, то выведем общее значение Free (estimated). Именно поэтому эта метрика имеет estimated. Это не точная цифра, а лишь примерная. На практике нужно понимать, что значение Free (estimated) касается Data, а не Metadata. Это вводит в заблуждение.
Другими словами, эта метрика про заполнение чистыми данными, а не про увеличение метаданных. Если в разделе не останется Device unallocated, а нужно будет выделить новый чанк для Metadata, то BTRFS просто вернёт no space left.
Фрагментация и балансировка
Особенно эта проблема чувствуется при фрагментации данных, когда большое количество чанков типа DATA заполнено не полностью и поэтому не может быть деаллоцировано. Степень такой фрагментации легко понять по большой (на порядок) разнице между значением Free (estimated) и значением Device unallocated.
Пример на скриншоте выше явно относится к этому случаю. У меня 330G в Free, но всего 25G в Unallocated. Есть небольшой трюк для перепаковки данных в чанках.
$ sudo btrfs balance start -dusage=10 /home/
Done, had to relocate 9 out of 7275 chunks
После выполнения этой операции, данные из чанков, заполненных меньше, чем на 10% (-dusage=10) были перенесены в другие чанки, где ещё есть свободное место. В результате 9 чанков (9G) было очищено и деаллоцировано, а значение метрики Device unallocated, по настоящему свободного места, увеличилось до 34G.
Ну, а на этом на сегодня всё :)