Btrfs en SSD, "no queda espacio en el dispositivo"; catch-22 con `fstrim` y `btrfs balance`; ¿cómo recuperarse?

Btrfs en SSD, "no queda espacio en el dispositivo"; catch-22 con `fstrim` y `btrfs balance`; ¿cómo recuperarse?

El sistema de archivos raíz de mi Kubuntu (montado en /) es Btrfs. No lo uso -o discardcomo opción de montaje. Esto significaNecesito ejecutar fstrimbajo demanda.

En el pasado encontré este problema:btrfs, no queda espacio en disco. Noté fstrim -v /que casi no se recortaba espacio. Mi solución fue ejecutar btrfs balance start /antes fstrim. Esta es la esencia demi respuesta ahí.

Hoy es diferente. Quizás llego demasiado tarde con el mantenimiento. Esto es lo que pasa:

# fstrim -v /
/: 24 KiB (24576 bytes) trimmed
# btrfs balance start /
ERROR: error during balancing '/': No space left on device

Eliminé algunos subvolúmenes (instantáneas) btrfs subvolume delete …y no ayudó. No recuerdo muy bien los detalles, pero creo que anteriormente podía ejecutar btrfs balance …porque el corte preliminar fstrimrecortó al menos unos pocos MiB, no tan solo 24 KiB como hoy. Ahora parece una situación complicada en la que fstrimo btrfs balancesólo funcionaría si el otro hiciera su trabajo primero.

Para que conste, estas son algunas estadísticas que muestran que, de hecho, tengo mucho espacio:

# 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

Tenga en cuenta que todavía no me queda "espacio en el dispositivo" durante el funcionamiento normal. Creo que Btrfs sigue incorporando nuevas escrituras dentro de fragmentos ya tomados. Sin embargo, en el pasado presioné "no queda espacio..." durante apt-get upgrade, luego me recuperé con btrfs balancey fstrim. No sé cuándo (si) esto me golpea de nuevo. Me gustaría hacer mi mantenimiento antes de que "no quede espacio..." cuando hago algo importante.

¿Cómo salir de esta situación para fstrimno btrfs balancebloquearnos unos a otros?¿Puedo solucionar este problema desde mi sistema en ejecución?

De hecho, ya solucioné esto, mi respuesta está a continuación. La pregunta es para referencia futura. No dude en agregar otra solución.


Información adicional:

$ 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

Respuesta1

Sí, puede recuperarse desde su sistema en ejecución. Mi enfoque original está abajo; sin embargo, gracias al comentario de Zan Lynx encontré una manera más sencilla.

Mi enfoque mejorado

Este es el comentario mencionado:

O si está pensando en el futuro, puede decirle a btrfs que use menos del máximo del dispositivo conbtrfs filesystem resize

(En comparación con mi enfoque original, el punto es tener deliberadamente algo de espacio libre en este dispositivo en particular y expandir el sistema de archivos allí, en lugar de agregar un dispositivo separado, lo que puede no ser tan fácil).

Buenas noticias: ¡mis pruebas indican que no tengo que pensar en el futuro! Incluso si btrfs balance start /arroja "no queda espacio ...", aún puedo reducir el sistema de archivos, siempre que haya espacio para él (es decir, todos los archivos y metadatos caben en el nuevo tamaño). Esto lleva a la siguiente solución:

# 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

Mi enfoque original

Esto es lo que debe hacer (descripción detallada a continuación):

  1. Agregue un dispositivo adicional al sistema de archivos Btrfs.
  2. btrfs balance start …
  3. fstrim …
  4. Elimine el dispositivo adicional del sistema de archivos Btrfs.
  5. btrfs balance start …
  6. fstrim …

El truco consiste en agregar un dispositivo adicional al sistema de archivos Btrfs, para btrfs balance …tener algo de espacio adicional. El dispositivo puede ser como /dev/sdbo /dev/sdb3. En este ejemplo estoy usando un archivo normal de 1 GiB en mi HDD (muy importante:¡Vuelvo a verificar que el archivo no pertenece al sistema de archivos Btrfs que quiero expandir! esto podría ser fatal). Creo que un archivo en la RAM (por ejemplo, en /dev/shm/) debería funcionar igual de bien.

# tmpf=/mnt/hdd/tempfile   # if this file exists, it will be overwritten!
# truncate -s 1G "$tmpf"
# extra=$(losetup -f --show "$tmpf")

Ahora $extraes como /dev/loop0o algo así.

# btrfs device add "$extra" /

En este momento no debo reiniciar mi sistema operativo. Si lo hiciera, le faltaría una parte de su sistema de archivos raíz porque no /dev/loop*estaría asociado con /mnt/hdd/tempfile. Esto no será un problema si utiliza un dispositivo normal (o una partición) como dispositivo adicional porque btrfs device scanlo detectará durante el arranque.

# btrfs balance start /

En mi caso, tempfilees un archivo disperso. En otra consola lo ejecuto watch ls -hls /mnt/hdd/tempfiley noto cuando crece hasta su tamaño (casi) completo. De esta manera sé cuándo se mueven algunos fragmentos de Btrfs del SSD. Ante cualquier duda, terminemos btrfs ballance …; pero invoco btrfs balance cancel /para ahorrar algo de tiempo. Ahora volvamos a la consola principal.

Nota: la primera línea a continuación es del btrfs balance start /comando anterior que fue interrumpido.

balance canceled by user
# fstrim -v /
/: 26,7 GiB (28696862720 bytes) trimmed

fstrimrecortado mucho más que antes. Ya no necesito mi dispositivo adicional.

# 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

Y esto es todo. Ahora es el momento de limpiar:

# losetup -d "$extra"
# rm "$tmpf"

información relacionada