web-dev-qa-db-ja.com

SSD上のBtrfs、「デバイスにスペースが残っていません」; `fstrim`と` btrfsbalance`を使用したcatch-22;回復する方法は?

私のKubuntuのルートファイルシステム(/の下にマウントされています)はBtrfsです。マウントオプションとして-o discardを使用していません。つまり、 オンデマンドでfstrimを実行する必要があります

過去に私はこの問題にぶつかりました: btrfs、ディスクスペースが残っていませんfstrim -v /は、トリミングされているスペースがほとんどないことに気づきました。私の解決策は、fstrimの前にbtrfs balance start /を実行することでした。これが 私の答え の要点です。

今日は違います。多分私はメンテナンスに遅すぎます。これが起こることです:

# 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 KiBではなく、少なくとも数MiBをトリミングしたためです。今では、fstrimまたはbtrfs balanceが、もう一方が最初に仕事をした場合にのみ機能するというキャッチ22の状況のようです。

記録のために、これらは私が実際に十分なスペースを持っていることを示すいくつかの統計です:

# 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
4

はい、実行中のシステム内から回復できます。私の最初のアプローチは以下のとおりです。しかし、Zan Lynxのコメントのおかげで、私はもっと簡単な方法を見つけました。

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

これは言及されたコメントです:

または、先を考えている場合は、btrfs filesystem resizeを使用してデバイスの最大数より少ない数を使用するようにbtrfsに指示できます。

(私の元のアプローチと比較すると、ポイントは、それほど簡単ではないかもしれない別のデバイスを追加するのではなく、この特定のデバイスに意図的に空き領域を確保し、そこでファイルシステムを拡張することです。)

良いニュース:私のテストは、私が先を考える必要がないことを示しています! 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"
5