SSD 上の Btrfs、「デバイスに空き容量がありません」; `fstrim` と `btrfs balance` のジレンマ; 回復方法は?

SSD 上の Btrfs、「デバイスに空き容量がありません」; `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 …が、役に立ちませんでした。詳細はよく覚えていませんが、以前は少なくとも数 MiB をbtrfs balance …予備的にトリミングしていたため、実行できたと思います。現在のように 24 KiB ほど小さくはなかったのです。現在は、またはが先に機能しないと、もう一方だけが機能しないという、ジレンマfstrimの状況のようです。fstrimbtrfs 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 balancefstrim

この状況から回復しfstrimbtrfs 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

はい、実行中のシステム内から回復できます。私のオリジナルのアプローチは下記にありますが、Zan Lynx のコメントのおかげで、より簡単な方法を見つけることができました。

私の改善されたアプローチ

言及されているコメントは次のとおりです:

あるいは、先を見越して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。この例では、HDD 上の通常の 1 GiB ファイルを使用しています (非常に重要:ファイルが、拡張したい Btrfs ファイルシステムに属していないことを再確認しました。これは致命的になる可能性があります。RAM 内のファイル (たとえば、 内/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" /

現時点では、OS を再起動してはいけません。再起動すると、 が/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"

関連情報