Btrfs Scrub 使用ガイド:データ検証、自動修復、定期メンテナンス

Btrfs scrub の役割、コマンド、auto-repair の条件、NOCOW file のリスク、read-only scrub の注意点、定期巡回の間隔、bandwidth limiting を整理する。

Btrfs scrub は、Btrfs の日常メンテナンスで最も重要で、同時に誤解されやすい機能の一つである。これは伝統的な意味の fsck ではない。filesystem data と metadata を読み、checksum、superblock、metadata block header、disk read error を検証し、信頼できる replica がある場合に修復を試みる online validation pass である。

NAS、home server、backup disk、multi-device array で Btrfs を使っているなら、scrub は定期メンテナンスに入れるべきだ。価値は「壊れてから修理する」ことではなく、disk がまだ読めて、array に good replica が残っている段階で silent corruption を早期に見つけることにある。

scrub は何を確認するのか

Btrfs の公式ドキュメントによると、scrub は filesystem data と metadata を走査し、主に次を確認する。

  • data block checksum error。
  • basic super block error。
  • basic metadata block header error。
  • disk read error。

RAID1 のような replicated block group profile を使う filesystem では、read-write mount 上の scrub が一部の損傷を自動修復できる。修復は魔法ではない。別の replica から検証済みの good data をコピーするだけである。

ここが重要だ。scrub の修復能力は「利用可能な good copy が存在すること」に依存する。single disk に data が一つしかない場合、scrub は checksum error を検出できても、元の内容を自力で復元することは通常できない。

よく使うコマンド

mount point に対して scrub を開始する。

1
sudo btrfs scrub start /

foreground で実行し、結果を手動で観察する。

1
sudo btrfs scrub start -B /

status を確認する。

1
sudo btrfs scrub status /

実行中の scrub を cancel する。

1
sudo btrfs scrub cancel /

中断された scrub を resume する。

1
sudo btrfs scrub resume /

Btrfs の mount path を指定すると、その filesystem 内の全 device を並列に scrub する。device を指定した場合は、その device だけを scrub する。ただし指定 device 上の replica が読めない、または検証に失敗した場合、Btrfs は他の device から good copy を読むことを試みる。

scrub は fsck ではない

最もよくある誤解がこれだ。scrub は btrfs check ではなく、伝統的な filesystem checker でもない。

scrub ができること:

  • checksum を使って data または metadata corruption を検出する。
  • 他に信頼できる replica がある場合に自動修復する。
  • disk read error と一部の基本構造 error を検出する。

scrub ができないこと:

  • good replica がない data を再構築する。
  • offline filesystem check を置き換える。
  • 複雑な tree structure corruption をすべて修復する。
  • application-level file content が必ず正しいと保証する。

filesystem structure が深刻に壊れている場合、専門家の助言のもとで btrfs check などの tool が必要になることがある。scrub を万能修復コマンドとして扱ってはいけない。

NOCOW file のリスク

Btrfs 公式ドキュメントは重要な注意点を挙げている。chattr +C で file に NOCOW attribute を設定すると、現在の実装では暗黙に NODATASUM が有効になる。つまり、その file data 自体には checksum がない。

scrub はこれらの file の metadata を検証し修復できるが、file data の内容は検証できない。multi-replica setup では特に問題になる。ある NOCOW file の一つの copy が壊れても、Btrfs にはどの replica が正しいか判断する data checksum がないため、壊れた内容を user space tool に返す可能性がある。

一部の application は performance のために +C を default で使う。systemd journal や一部の libvirt storage pool が代表例である。VM image、database、log directory では性能上の理由があるが、普通の COW file と同じように scrub が data content を守ってくれるとは期待できない。

read-only scrub でも書き込みが起こり得る

もう一つ直感に反する点がある。read-write mounted filesystem で read-only scrub を実行しても、いくつかの write が発生する可能性がある。

公式ドキュメントによると、これは block group を read-only として mark することと block group items を write back することの race を避けるための design limitation である。完全に write のない scrub を望むなら、read-only mounted filesystem 上で read-only scrub を実行する必要がある。read-write mount に read-only scrub option を付けるだけでは不十分だ。

一般ユーザーにとっての意味は次の通り。

  • 日常の online scrub は read-write mount 上で実行できる。
  • forensic、failure analysis、非常に保守的な read-only check では、先に mount state を確認する。
  • read-only scrub を絶対に zero-write だと解釈しない。

中断と再開

新しい kernel では、scrub は suspend、hibernate、filesystem freezing、cgroup freezing、pending signals などで中断されることがある。中断後、実行中の scrub は cancel されるが、btrfs scrub resume で保存位置から再開できる。

scrub status は次の場所に記録される。

1
/var/lib/btrfs/

file name は通常次のようになる。

1
2
scrub.status.UUID
scrub.progress.UUID

status file は定期的に更新される。resume した scrub は、完全に最初からではなく、最後に保存された位置から続行する。

どれくらいの頻度で実行するか

公式の推奨は月 1 回である。実際には data の重要性と disk 状態に合わせて調整する。

よくある schedule:

  • Home NAS:月 1 回。
  • Backup disk:長時間接続した後、または月 1 回。
  • 重要な multi-device array:月 1 回、必要ならより頻繁に。
  • New disk migration や disk 不良の疑い:migration 後すぐに実行。

scrub は idle filesystem でも device bandwidth の約 80% を使う可能性があるため、peak workload 中に実行しないほうがよい。HDD array では scrub 中に latency がかなり上がることがある。SSD でも read amplification と background pressure は増える。

scrub の bandwidth を制限する

以前は ionice で foreground I/O への影響を下げる方法がよく使われた。しかし公式ドキュメントは、すべての I/O scheduler で同じように support されるわけではないと注意している。CFQ はすでに一般的ではない。BFQ は関連 priority behavior を support するが、使う前に理解しておく必要がある。mq-deadline のような一般的 scheduler では、cgroup2 I/O controller や Btrfs 専用の limit のほうが適している。

systemd で read bandwidth を制限する例:

1
sudo systemd-run -p "IOReadBandwidthMax=/dev/sdx 10M" btrfs scrub start -B /

Linux 5.14 以降では、Btrfs 専用の sysfs interface で device ごとの scrub limit を設定できる。

1
echo 100m | sudo tee /sys/fs/btrfs/FSID/devinfo/DEVID/scrub_speed_max

現在の limit を表示する。

1
sudo btrfs scrub limit /

この設定は永続化されず、filesystem を unmount すると失われる。実際の system に合わせて FSIDDEVID を置き換える必要がある。まず次を確認する。

1
2
sudo btrfs filesystem show /
ls /sys/fs/btrfs/

実用的なメンテナンス手順

堅実な Btrfs メンテナンス手順は次のようにできる。

1
2
3
4
sudo btrfs scrub start -B /
sudo btrfs scrub status /
sudo btrfs device stats /
dmesg -T | grep -Ei "btrfs|checksum|i/o error|read error"

scrub が corrected errors を報告した場合、Btrfs は good replica から data を修復したという意味だが、無視してよいわけではない。disk SMART、cable、power、controller、Btrfs device stats を続けて確認するべきだ。

scrub が uncorrectable errors を報告した場合、Btrfs は good copy を見つけられなかった。まだ読める data をできるだけ早く backup し、affected file または device を特定し、必要に応じて disk replacement や backup からの restore を行う。

まとめ

Btrfs scrub の役割は明確だ。online data verification と replica repair の tool であり、fsck ではなく、backup でもない。

checksum と redundant replica がある Btrfs filesystem で、silent corruption を定期的に見つけ、good copy から復元する用途に最も向いている。checksum のない NOCOW file data は保護できず、good replica がない場合に壊れた内容を復元することもできない。

重要な data を Btrfs に置くなら、月 1 回 scrub を実行し、SMART、device stats、backup、alerting と組み合わせるべきだ。信頼できる data safety は、checksum、redundancy、monitoring、backup が一緒に働くことで実現する。単一の command に依存するものではない。

参考リンク:

记录并分享
Hugo で構築されています。
テーマ StackJimmy によって設計されています。