Btrfs на SSD, «на устройстве не осталось места»; ловушка-22 с `fstrim` и `btrfs balance`; как восстановить?

Btrfs на SSD, «на устройстве не осталось места»; ловушка-22 с `fstrim` и `btrfs balance`; как восстановить?

Корневая файловая система моего 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

Мой оригинальный подход

Вот что вам нужно сделать (подробное описание ниже):

  1. Добавьте дополнительное устройство в файловую систему Btrfs.
  2. btrfs balance start …
  3. fstrim …
  4. Удалите лишнее устройство из файловой системы Btrfs.
  5. btrfs balance start …
  6. 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"

Связанный контент