Btrfs no SSD, “nenhum espaço deixado no dispositivo”; catch-22 com 'fstrim' e 'btrfs balance'; como recuperar?

3

O sistema de arquivos raiz do meu Kubuntu (montado em / ) é o Btrfs. Eu não uso -o discard como uma opção de montagem. Isso significa que eu preciso executar fstrim sob demanda .

No passado, eu tive esse problema: btrfs, nenhum espaço em disco sobrando . Percebi que fstrim -v / mostrou quase nenhum espaço sendo aparado. Minha solução foi executar btrfs balance start / antes de fstrim . Esta é a essência da minha resposta .

Hoje é diferente. Talvez eu esteja atrasado demais com a manutenção. Isso é o que acontece:

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

Eu deletei alguns subvolumes (snapshots) com btrfs subvolume delete … e isso não ajudou. Não me lembro de detalhes muito bem, mas acho que anteriormente eu poderia executar btrfs balance … porque o fstrim preliminar aparou pelo menos alguns MiB, não tão pouco quanto 24 KiB como hoje. Agora, parece uma situação difícil, em que fstrim ou btrfs balance só funcionaria se o outro fizesse seu trabalho primeiro.

Para registro, essas são algumas estatísticas que mostram que eu tenho bastante espaço:

# 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

Note que ainda não tenho "espaço disponível no dispositivo" durante a operação normal. Eu acho que o Btrfs continua ajustando novas escritas dentro de partes já tomadas. No entanto, no passado, pressionei "sem espaço sobrando ..." durante apt-get upgrade , depois recuperei com btrfs balance e fstrim . Eu não sei quando (se) isso me atinge novamente. Eu gostaria de fazer minha manutenção antes de "não ter mais espaço ..." ao fazer algo importante.

Como recuperar-se dessa situação, então fstrim e btrfs balance não bloqueiam um ao outro? Posso corrigir isso de dentro do meu sistema em execução?

Na verdade, eu já consertei isso, minha resposta está abaixo. A questão é para referência futura. Sinta-se à vontade para adicionar outra solução.

Informações adicionais:

$ 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
    
por Kamil Maciorowski 04.04.2018 / 01:29

1 resposta

4

Sim, você pode se recuperar de dentro do seu sistema em execução. Minha abordagem original está abaixo; no entanto, graças ao comentário de Zan Lynx, encontrei uma maneira mais fácil.

Minha abordagem aprimorada

Este é o comentário mencionado:

Or if you're thinking ahead you can tell btrfs to use less than maximum of the device with btrfs filesystem resize

(Comparando com a minha abordagem original, o ponto é deliberadamente ter algum espaço livre neste dispositivo em particular e expandir o sistema de arquivos lá, em vez de adicionar um dispositivo separado que pode não ser tão fácil.)

Boas notícias: meus testes indicam que não preciso pensar no futuro! Mesmo que btrfs balance start / não "tenha espaço sobrando ...", ainda posso reduzir o sistema de arquivos, se houver espaço para isso (ou seja, todos os arquivos e metadados se encaixam no novo tamanho). Isso leva à seguinte solução:

# 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

Minha abordagem original

Isso é o que você precisa fazer (descrição detalhada abaixo):

  1. Adicione um dispositivo extra ao sistema de arquivos do Btrfs.
  2. btrfs balance start …
  3. fstrim …
  4. Exclua o dispositivo extra do sistema de arquivos Btrfs.
  5. btrfs balance start …
  6. fstrim …

O truque é adicionar um dispositivo extra ao sistema de arquivos Btrfs, então btrfs balance … tem algum espaço adicional. O dispositivo pode ser como /dev/sdb ou /dev/sdb3 . Neste exemplo estou usando um arquivo regular de 1 GiB no meu disco rígido ( muito importante: eu verifiquei o arquivo não pertence ao sistema de arquivos Btrfs que eu quero expandir! Isso pode ser fatal). Eu acho que um arquivo na RAM (por exemplo, em /dev/shm/ ) deve fazer o mesmo.

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

Agora, $extra é como /dev/loop0 ou algo assim.

# btrfs device add "$extra" /

Neste momento, não devo reiniciar o sistema operacional. Se eu fizesse isso, faltaria uma parte de seu sistema de arquivos raiz porque nenhum /dev/loop* estaria associado a /mnt/hdd/tempfile . Isto não será um problema se você usar um dispositivo regular (ou uma partição) como o dispositivo extra porque btrfs device scan durante a inicialização irá detectá-lo.

# btrfs balance start /

No meu caso, o tempfile é um arquivo esparso. Em outro console eu corro watch ls -hls /mnt/hdd/tempfile e noto quando ele cresce para o tamanho (quase) completo. Desta forma eu sei quando alguns pedaços de Btrfs são movidos do SSD. Em caso de dúvida, deixe btrfs ballance … terminar; mas eu invoco btrfs balance cancel / para economizar algum tempo. Agora vamos voltar para o console principal.

Nota: a primeira linha abaixo é do comando btrfs balance start / acima que foi interrompido.

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

fstrim aparou muito mais do que antes. Eu não preciso mais do meu dispositivo extra.

# 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

E é isso. Agora é hora de limpar:

# losetup -d "$extra"
# rm "$tmpf"
    
por 04.04.2018 / 01:29