Корневая файловая система моего Kubuntu (смонтированная в /
) — Btrfs. Я не использую -o discard
как вариант монтирования. Это означает, чтоМне нужно работать fstrim
по требованию.
В прошлом я сталкивался с этой проблемой:btrfs, места на диске не осталось. Я заметил fstrim -v /
, что почти не было места для обрезки. Мое решение было запустить btrfs balance start /
до fstrim
. Это сутьмой ответ там.
Сегодня все по-другому. Может быть, я опоздал с обслуживанием. Вот что происходит:
# fstrim -v /
/: 24 KiB (24576 bytes) trimmed
# btrfs balance start /
ERROR: error during balancing '/': No space left on device
Я удалил несколько подтомов (снимков) с помощью , btrfs subvolume delete …
и это не помогло. Я не очень хорошо помню детали, но я думаю, что раньше я мог работать, btrfs balance …
потому что предварительно fstrim
обрезал по крайней мере несколько МиБ, а не так мало, как 24 КиБ, как сегодня. Теперь это похоже на ситуацию «уловки-22», где fstrim
или btrfs balance
сработает только если другой сделает свою работу первым.
Для справки, вот некоторая статистика, которая показывает, что у меня на самом деле предостаточно места:
# df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 112G 43G 68G 39% /
# btrfs fi df /
Data, single: total=108.73GiB, used=41.00GiB
System, single: total=64.00MiB, used=16.00KiB
Metadata, single: total=3.00GiB, used=1.02GiB
GlobalReserve, single: total=352.00MiB, used=0.00B
Обратите внимание, что у меня пока нет сообщения «на устройстве не осталось места» при нормальной работе. Я думаю, что Btrfs продолжает помещать новые записи в уже занятые фрагменты. Однако в прошлом я нажимал «нет места…» во время apt-get upgrade
, затем я восстанавливался с помощью btrfs balance
и fstrim
. Я не знаю, когда (если) это снова меня поразит. Я хотел бы провести обслуживание до того, как я получу сообщение «нет места…» при выполнении чего-то важного.
Как выйти из этой ситуации fstrim
и btrfs balance
не блокировать друг друга?Могу ли я исправить это из моей работающей системы?
На самом деле я уже исправил это, мой ответ ниже. Вопрос для будущего использования. Не стесняйтесь добавлять другое решение.
Дополнительная информация:
$ uname -a
Linux foobar 4.4.0-78-generic #99-Ubuntu SMP […] x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/issue
Ubuntu 16.04.3 LTS \n \l
# dpkg -l | grep btrfs
ii btrfs-tools 4.4-1ubuntu1 amd64 Checksumming Copy on Write Filesystem utilities
решение1
Да, вы можете восстановиться в рамках вашей беговой системы. Мой первоначальный подход ниже; однако, благодаря комментарию Зан Линкс я нашел более простой способ.
Мой улучшенный подход
Вот упомянутый комментарий:
Или, если вы думаете наперед, вы можете указать btrfs использовать меньше максимального объема устройства с помощью
btrfs filesystem resize
(Если сравнивать с моим первоначальным подходом, смысл в том, чтобы намеренно иметь немного свободного места на этом конкретном устройстве и расширить там файловую систему, а не добавлять отдельное устройство, что может оказаться не так просто.)
Хорошие новости: мои тесты показывают, что мне не нужно думать заранее! Даже если btrfs balance start /
выдает "места не осталось...", я все равно могу сжать файловую систему, если только для этого есть место (т. е. все файлы и метаданные вписываются в новый размер). Это приводит к следующему решению:
# btrfs filesystem resize -100M / # shrink a little...
Resize '/' of '-100M'
# btrfs filesystem resize +100M / # ... and expand back
Resize '/' of '+100M'
# btrfs balance start / # should work now
Done, had to relocate 88 out of 88 chunks
# fstrim -v /
/: 67,8 GiB (72753831936 bytes) trimmed
Мой оригинальный подход
Вот что вам нужно сделать (подробное описание ниже):
- Добавьте дополнительное устройство в файловую систему Btrfs.
btrfs balance start …
fstrim …
- Удалите лишнее устройство из файловой системы Btrfs.
btrfs balance start …
fstrim …
Хитрость заключается в том, чтобы добавить дополнительное устройство в файловую систему Btrfs, чтобы btrfs balance …
получить дополнительное пространство. Устройство может быть таким /dev/sdb
или /dev/sdb3
. В этом примере я использую обычный файл размером 1 ГиБ на моем жестком диске (очень важно:Я дважды проверяю, не принадлежит ли файл файловой системе Btrfs, которую я хочу расширить! Это может быть фатально). Я думаю, что файл в оперативной памяти (например, в /dev/shm/
) тоже подойдет.
# tmpf=/mnt/hdd/tempfile # if this file exists, it will be overwritten!
# truncate -s 1G "$tmpf"
# extra=$(losetup -f --show "$tmpf")
Сейчас $extra
что-то вроде /dev/loop0
того.
# btrfs device add "$extra" /
В этот момент я не должен перезагружать свою ОС. Если бы я это сделал, то у нее не было бы части корневой файловой системы, поскольку не /dev/loop*
было бы связано с /mnt/hdd/tempfile
. Это не будет проблемой, если вы используете обычное устройство (или раздел) в качестве дополнительного устройства, поскольку btrfs device scan
во время загрузки оно будет обнаружено.
# btrfs balance start /
В моем случае tempfile
это разреженный файл. В другой консоли я запускаю watch ls -hls /mnt/hdd/tempfile
и замечаю, когда он вырастает до своего (почти) полного размера. Таким образом я узнаю, когда некоторые фрагменты Btrfs перемещаются с SSD. Если есть какие-либо сомнения, дайте btrfs ballance …
закончить; но я вызываю btrfs balance cancel /
, чтобы сэкономить немного времени. Теперь вернемся к главной консоли.
Примечание: первая строка ниже взята из btrfs balance start /
прерванной выше команды.
balance canceled by user
# fstrim -v /
/: 26,7 GiB (28696862720 bytes) trimmed
fstrim
подстригся гораздо больше, чем раньше. Мне больше не нужно мое дополнительное устройство.
# btrfs device delete "$extra" / # may take a while
# btrfs balance start / # should work now
Done, had to relocate 88 out of 88 chunks
# fstrim -v /
/: 67,8 GiB (72753831936 bytes) trimmed
И вот оно. Теперь пора чистить:
# losetup -d "$extra"
# rm "$tmpf"