HC620で発生したBtrfs zoned障害2件の検証:デッドロック、読み取り専用化、カーネル調査

Ubuntu 26.04とLinux 7.0.0-28でHC620に発生したBtrfs cleanerのデッドロックとトランザクション中断による読み取り専用化を、ログ、復旧コマンド、データ検証、カーネル試験計画とともに詳しく検証します。

This is a real fault review.環境は、Western Digital HC620 ホスト管理 SMR ハードディスクで、ゾーン化された Btrfs を使用し、/mnt/disk1 にマウントされています。システムは Ubuntu 26.04 LTS、カーネルは次のとおりです。

1
Linux data-server 7.0.0-28-generic

この障害は通常のハードディスクの速度低下ではなく、次の 2 つの重大な異常が相次いで発生しました。

  1. btrfs-cleaner および btrfs-transaction は中断不可能な D 状態になり、ファイル システムはアンマウントできません。
  2. Btrfs トランザクションは -11 で中止され、カーネルはファイル システムを読み取り専用にアクティブに切り替えます。

どちらの障害も、数TB規模の削除、データコピー、ゾーン領域の再利用が重なる状況で発生しました。システムの再インストールや btrfs check --repair は行っていません。本記事では、同様の障害を調査する際の参考になるよう、実際のログ、判断過程、コマンド、未確認事項をできる限り残しています。

注: これは、「HC620 上のすべての Btrf が壊れているに違いない」ことを証明するものではなく、コール スタックだけから特定のカーネル パッチを判断することもできません。この記事に記載されているカーネルお​​よび Ubuntu ソフトウェア パッケージのバージョンは、2026 年 7 月 24 日時点のオンサイト情報です。実際の操作の前に、現在のウェアハウスを再クエリする必要があります。

環境と発生までの流れ

このディスクには主にバックアップ データとコールド データが保存されます。最初の障害が発生するまでの動作はおおよそ次のとおりです。

1
2
3
4
删除约 3TB 旧数据
→ 从另一块盘复制约 3TB 新数据
→ Btrfs 后台清理与新写入重叠
→ btrfs-cleaner 锁死

HC620 はホスト管理型 SMR です。ディスクはゾーンごとに管理されます。各ゾーンはサイト上では次のように表示されます。

1
Device zone size: 256.00MiB

この種のデバイスでは、通常のCMR HDDのように、書き込み済みゾーンを自由に上書きできません。ファイルを削除してもデータブロックへの参照が外れるだけです。無効化された領域を再利用するには、ブロックグループの回収、有効データの移動、ゾーンのリセットを待つ必要があります。Btrfsではこの領域を次のように表示します。

1
Device zone unusable

したがって、「3TB を削除し、すぐに 3TB を書き込む」ということは、単に削除とコピーを加えたものではありません。バックグラウンドで同時に起こっている可能性があります:

1
2
3
4
5
6
7
提交删除事务
删除空 block group
回收旧 chunk
finish/reset zone
分配新 chunk
激活新 zone
持续写入新数据

これは、その後のコール スタックの分析における重要な背景になります。

最初の失敗: btrfs-cleaner が長時間ブロックされました

初期ログには次の内容が含まれます。

1
2
3
INFO: task btrfs-cleaner:1488 blocked for more than 368 seconds.
Not tainted 7.0.0-28-generic #28-Ubuntu
task:btrfs-cleaner state:D pid:1488

主要な呼び出しチェーンは次のとおりです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
__mutex_lock_slowpath
mutex_lock
btrfs_chunk_alloc
btrfs_inc_block_group_ro
do_zone_finish
btrfs_zone_finish_one_bg
btrfs_zoned_activate_one_bg
reserve_chunk_space
check_system_chunk
btrfs_remove_chunk
btrfs_delete_unused_bgs
cleaner_kthread

下から上に読むと、プロセスは次のとおりです。

1
2
3
4
5
6
7
btrfs-cleaner 清理未使用的 block group
→ 删除旧 chunk
→ 检查并预留 system chunk 空间
→ 激活 zoned block group
→ finish 一个 zone
→ 再次进入 chunk 分配
→ 等待 mutex

ログは、ミューテックスが同じ btrfs-cleaner スレッドによって保持されている可能性があることも示しています。呼び出しチェーンと組み合わせると、ブロック グループの削除、ゾーンの終了、および新しいチャンクの割り当てが重なったときに、クリーニング スレッドがロック待機状態に入ることがオンサイトで判断されます。その後、Btrfs フラッシュを待機している btrfs-transaction および kworker もブロックされました。

これはオンサイトのコール スタックの説明であり、対応する上流のバグのみが見つかったことを意味するものではありません。確かなことは次のとおりです。

  • ゾーン化された Btrfs のブロック グループ/チャンク クリーンアップ パスでブロッキングが発生します。
  • スレッドはカーネル状態で D 状態に入りました。
  • 通常の kill -9 はカーネル スレッドを終了できません。
  • トランザクションのコミットに依存する継続的な操作がスタックする可能性があります。

そもそもどのようなチェックが行われたのでしょうか?

まず、rsnapshot、rsync、Docker コンテナ、またはその他のディスク書き込みタスクを停止し、次に中断不可能なプロセスを確認します。

1
2
ps -eo state,pid,ppid,comm,wchan:35,args | \
awk 'NR==1 || $1 ~ /^D/'

この起動時のカーネル ログを保存します。

1
2
3
4
5
sudo journalctl -k -b \
  > /root/btrfs-hang-$(date +%F-%H%M).log

sudo dmesg -T | \
grep -iE 'btrfs|hung task|I/O error|ata|blk_update'

関連するスレッド スタックを保存します。

1
2
sudo cat /proc/1488/stack
sudo cat /proc/1489/stack

ファイル システムにクエリを実行するときにタイムアウトを追加して、診断コマンド自体が永続的にブロックされないようにします。

1
2
sudo timeout 15s btrfs device stats /mnt/disk1
sudo timeout 15s btrfs filesystem usage /mnt/disk1

次に、通常のアンインストールを試します。

1
2
cd /
sudo timeout 60s umount /mnt/disk1

消す:

1
umount: /mnt/disk1: target is busy.

target is busy はカーネル ロックアップとは異なります

target is busy は通常、次の参照がまだ利用可能であることを意味します。

  • プロセスの現在の作業ディレクトリは /mnt/disk1 にあります。
  • ファイルはまだ開いています。
  • バックアップまたはコピー プログラムはまだ実行中です。
  • /mnt/disk1 の下にサブマウント ポイントがあります。
  • ファイル システムのロックにより、ユーザー プロセスが D 状態になりました。

まず、すべての端末がマウント ディレクトリから出ていることを確認します。

1
2
cd /
pwd

サブマウントと占有者を確認します。

1
2
3
4
sudo findmnt -R /mnt/disk1
sudo timeout 15s fuser -vmM /mnt/disk1

pgrep -af 'rsnapshot|rsync|borg|restic|tar|cp|mv|docker'

一般のユーザー プロセスは、強制終了を検討する前に正常に終了できます。

1
2
3
sudo kill -TERM 1234 5678
sleep 5
sudo kill -KILL 1234 5678

rsnapshot または rsync の場合:

1
2
3
4
5
sudo pkill -TERM -x rsnapshot
sudo pkill -TERM -x rsync
sleep 5
sudo pkill -KILL -x rsnapshot
sudo pkill -KILL -x rsync

ただし、殺そうとしないでください。

1
2
btrfs-cleaner
btrfs-transaction

これらはカーネル スレッドです。オンサイト検査の結果、主なブロッカーは Btrfs カーネル スレッドであり、killumount、またはグローバル sync を継続しても根本原因を解決できないことがわかりました。

遅延アンマウントまたは強制アンマウントが使用されないのはなぜですか?

当時は実装されていませんでした:

1
2
sudo umount -l /mnt/disk1
sudo umount -f /mnt/disk1

umount -l は、最初にディレクトリ ツリーからマウント ポイントを削除するだけで、実際のファイル システム参照は、クリーンアップされる前にビジー状態がなくなるまで待機する必要があります。 Btrfs トランザクションがロックされている場合、マウント ポイントが非表示になっているだけであり、データがコミットされたことやファイル システムがアンマウントされたことを意味するものではありません。

umount -f も、ローカルの Btrfs カーネルのデッドロックを軽減する信頼できる手段ではありません。これは、ネットワークの一部またはユーザーモードのファイル システムでより一般的に使用されます。

また、実行されていません:

1
2
3
4
5
6
sync
btrfs balance start /mnt/disk1
btrfs scrub start /mnt/disk1
btrfs filesystem defragment -r /mnt/disk1
mount -o remount,ro /mnt/disk1
btrfs check --repair /dev/sda

これらの操作は、すでに停止しているトランザクションを待ち続けるか、問題のあるブロックグループ回収パスへ再び入る可能性があります。

再起動する前に noauto を追加します

マシンの再起動直後に同じカーネルを使用してこのディスクを自動的に読み書きしないようにするには、まず /etc/fstab を確認します。

1
grep -n '/mnt/disk1' /etc/fstab

バックアップ構成:

1
2
3
4
sudo cp -a /etc/fstab \
  /etc/fstab.bak-$(date +%F-%H%M%S)

sudoedit /etc/fstab

たとえば、次のようになりました。

1
UUID=xxxx /mnt/disk1 btrfs defaults 0 0

一時的に次のように変更されました。

1
UUID=xxxx /mnt/disk1 btrfs defaults,noauto 0 0

noauto は、起動時に自動的にマウントされないことだけを意味し、ファイル システムが無効になることを意味しません。システムの起動後も、手動で読み取り専用または読み取り/書き込みでマウントできます。

通常の再起動から最後の手段まで

通常の再起動がサイトで実行されました。

1
sudo systemctl reboot

今度は正常に完了し、再起動後ファイルシステムを再マウントすることができました。 Btrfs が原因で通常の再起動が停止した場合、リスクに応じて適用レベルが段階的に増加します。

1
sudo systemctl reboot --force

最後の手段は次のとおりです。

1
sudo systemctl reboot --force --force

2 つの --force はサービスを停止せず、ファイル システムを通常どおりアンマウントしません。その影響はハード リセットに近く、コミットされていないデータが失われる可能性があります。システムが正常に終了できない場合にのみ使用でき、通常の再起動コマンドとしては使用できません。

再起動後の確認

まず、実際に起動されたカーネルとディスクを確認します。

1
2
3
uname -a
lsblk -o NAME,SIZE,MODEL,FSTYPE,MOUNTPOINTS
sudo smartctl -x /dev/sda

自動マウントがないことを確認します。

1
findmnt /mnt/disk1

初めて読み取り専用でマウントします。

1
sudo mount -o ro /dev/sda /mnt/disk1

実際の環境では、UUID または /dev/disk/by-id/ を最初に使用する必要があり、デフォルトのデバイスが必ずしも /dev/sda である必要はありません。

カーネル ログ、Btrfs デバイス数、およびスペースのステータスを確認します。

1
2
3
4
5
sudo dmesg -T | \
grep -iE 'btrfs|ata|I/O error|medium error|uncorrect|reset'

sudo btrfs device stats /mnt/disk1
sudo btrfs filesystem usage /mnt/disk1

ライブ btrfs device stats すべて 0:

1
2
3
4
5
[/dev/sda].write_io_errs    0
[/dev/sda].read_io_errs     0
[/dev/sda].flush_io_errs    0
[/dev/sda].corruption_errs  0
[/dev/sda].generation_errs  0

これは、Btrfs がデバイスの読み取りおよび書き込み、フラッシュ、検証、または生成エラーを記録しないことを示しており、これは良い兆候です。しかし、これはカーネルのロックアップが修正されたことを証明するものではなく、未読データの問題を排除するものでもありません。

スクラブでできることとできないこと

システムが安定した後にスクラブがスケジュールされます。

1
2
sudo btrfs scrub start /mnt/disk1
sudo btrfs scrub status /mnt/disk1

フロントデスクで結果を待ってもらいたい場合:

1
sudo btrfs scrub start -B /mnt/disk1

タスクをキャンセルします:

1
sudo btrfs scrub cancel /mnt/disk1

スクラブは、保存されたデータとメタデータを読み取り、Btrfs によって保存されたチェックサムをチェックします。これは、読み取りエラー、データまたはメタデータ検証エラーを見つけるために使用されます。次の場合ではありません。

1
2
3
4
5
6
碎片整理
空间回收
balance
坏道修复
完整 fsck
内核死锁修复

結果が次の場合:

1
Error summary: no errors found

この読み取りと検証で例外が見つからなかったことを示すことしかできませんが、btrfs-cleaner のゾーン化されたクリーンアップ パスが将来再びロックされないことを証明することはできません。

結果を保存します:

1
2
sudo btrfs scrub status /mnt/disk1 | \
sudo tee /root/btrfs-scrub-$(date +%F).log

スクラブ中に、rsync、rsnapshot、バランス、または一括削除を同時に実行しないでください。このタイプのバックアップ ディスクの場合、実際の使用量に基づいて 1 ~ 3 か月ごとにバックアップを実行できます。

「スペースの再利用」のためにバランスが実行されない理由

現場に現れた:

1
Data,single: 98.67%

この数値は、割り当てられたデータ ブロック グループの使用量を表すだけであり、ディスク全体の 1.33% だけが残っていることを意味するものではありません。その時点ではまだいくつかの TiB Device unallocated があり、引き続き割り当てを行うためのスペースが不足することはありませんでした。

したがって、実行はありません。

1
2
sudo btrfs balance start /mnt/disk1
sudo btrfs balance start -dusage=0 /mnt/disk1

Balance は、最初の障害が発生した場所にブロック グループを再配置します。

1
2
3
4
btrfs_delete_unused_bgs
btrfs_remove_chunk
btrfs_zoned_activate_one_bg
do_zone_finish

問題が発生したカーネルで balance を実行すると、同様のブロックグループ削除とゾーン回収のパスへ再び入る可能性があります。

数テラバイトの削除と書き込みを処理する方法

最も効果的なワークフロー調整は、十分なスペースがあるときに古いデータを削除する前に、新しいデータをコピーして検証することです。

1
2
3
4
先复制新数据
→ 校验复制结果
→ 暂停新写入并观察
→ 分批删除旧数据

コピー:

1
2
3
rsync -aHAX --info=progress2 \
  /来源目录/ \
  /mnt/disk1/目标目录/

容量の比較:

1
du -sh /来源目录 /mnt/disk1/目标目录

ターゲットを変更せずにコンテンツ検証方法を使用する練習をしてください。

1
2
3
rsync -aHAXnc \
  /来源目录/ \
  /mnt/disk1/目标目录/

先に削除する必要がある場合は、数TBを一度に削除せず、すぐに書き込んでください。日付、サブディレクトリ、または容量ごとに 200 ~ 500 GiB のバッチに分割できます。

1
2
rm -rf /mnt/disk1/旧数据/第一批
sudo btrfs filesystem sync /mnt/disk1

btrfs filesystem sync はファイル システム トランザクションをコミットし、関連するクリーンアップ作業をウェイクアップしますが、コマンドが返されても、すべてのブロック グループとゾーンの再利用が完了したことを意味するわけではありません。

Btrfs サブボリュームまたはスナップショットを削除する場合は、次のコマンドを実行することもできます。

1
sudo btrfs subvolume sync /mnt/disk1

これは、削除要求が送信されたサブボリュームのクリーンアップが完了するまで待機し、通常の rm -rf 削除には適用されません。

各バッチの後に確認します。

1
2
3
4
5
6
7
8
sudo btrfs filesystem usage /mnt/disk1
sudo btrfs device stats /mnt/disk1

ps -eo state,pid,comm,wchan:35,args | \
awk 'NR==1 || $1 ~ /^D/'

sudo journalctl -k --since "30 minutes ago" | \
grep -iE 'btrfs.*(blocked|hung|error|warning)|I/O error'

続行する前に、次の条件を満たしてください。

  • btrfs filesystem sync は正常に戻ります。
  • D 状態の Btrfs スレッドはありません。
  • カーネル ログには、新しいブロック、ハング、中止、または Btrfs エラーはありません。
  • ディスクアクティビティが大幅に低下しました。
  • Device zone unusable は急速に成長していません。

Device zone unusable をゼロにする必要はありません。次の回収条件に達するまで数十GiBのままになることがありますが、それだけでファイルシステムが停止しているとは判断できません。

優先順位と帯域幅を制限して、書き込みをバッチ処理することもできます。

1
2
3
4
sudo ionice -c2 -n7 nice -n 15 \
rsync -aHAX --info=progress2 --bwlimit=100M \
  /来源目录/ \
  /mnt/disk1/目标目录/

--bwlimit=100M は、保守的な出発点にすぎません。レート制限ではカーネルのバグを修正できませんが、クリーナー、トランザクションのコミット、ライトバック、およびゾーンのアクティブ化が同時に高負荷になる可能性を減らすことができます。複数の大規模な rsync を同時に実行しないでください。

zoned回収メトリクスを監視する

まずファイル システムの UUID を取得します。

1
2
3
4
FSID=$(sudo btrfs filesystem show /mnt/disk1 | \
       awk '/uuid:/ {print $NF; exit}')

echo "$FSID"

データ、メタデータ、システムのスペースと回復インジケーターを確認します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
for type in data metadata system; do
    echo "===== $type ====="
    base="/sys/fs/btrfs/$FSID/allocations/$type"

    grep -H . \
      "$base/bytes_pinned" \
      "$base/bytes_reserved" \
      "$base/bytes_may_use" \
      "$base/bytes_zone_unusable" \
      "$base/reclaim_count" \
      "$base/reclaim_bytes" \
      "$base/reclaim_errors" \
      "$base/periodic_reclaim" \
      "$base/dynamic_reclaim" \
      "$base/bg_reclaim_threshold" 2>/dev/null
done

で:

  • bytes_pinned: 通常、現在のトランザクションがコミットされるまで解放できないスペース。
  • bytes_zone_unusable: 有効期限が切れたが、直接再利用できないゾーン化されたスペース。
  • reclaim_count: 回収試行の累積回数。
  • reclaim_bytes: 回収済みバイト数の累積値。
  • reclaim_errors: 回収エラーの累積回数。

トランザクションのコミット統計を表示することもできます。

1
cat "/sys/fs/btrfs/$FSID/commit_stats"

max_commit_ms が数十秒または数百秒続く場合、またはログが再度表示される場合:

1
2
btrfs-cleaner blocked
btrfs-transaction blocked

バックアップ タスクを停止してログを保存し、データの注入を続行せず、自然に回復するまで待つ必要があります。

バックアップタスクの重複を無効にする

すべての rsnapshot サイクルは同じロックを使用します。

1
2
3
4
/usr/bin/flock -n /run/lock/rsnapshot.lock \
  /usr/bin/ionice -c2 -n7 \
  /usr/bin/nice -n 15 \
  /usr/bin/rsnapshot daily

weekly および monthly も以下を使用します。

1
/run/lock/rsnapshot.lock

これにより、毎日、毎週、毎月、および多数の rsync が同時に実行されることを回避できます。スクラブ、一括削除、および大規模コピーも、異なる期間にスケジュールする必要があります。

2 番目の失敗: トランザクションが中止され、読み取り専用が強制されました

最初の失敗と再起動の後、ファイル システムは正常にマウントでき、デバイス統計にエラーはありません。しかし、後で大量のデータを再度書き込むと、より明示的なトランザクション エラーが発生しました。

1
2
3
4
5
6
BTRFS error (device sda): error while writing out transaction: -11
BTRFS warning (device sda): Skipping commit of aborted transaction.
BTRFS: Transaction aborted (error -11)
BTRFS: error (device sda state A) in cleanup_transaction:2060:
errno=-11 unknown
BTRFS info (device sda state EA): forced readonly

動作環境は以下の通りです。

1
2
CPU: 0 PID: 1678 Comm: btrfs-transacti
Not tainted 7.0.0-28-generic #28-Ubuntu

今回は「一時的にスタック」しているわけではありませんが、トランザクションは中止されており、カーネルはファイル システムを保護するために積極的に読み取り専用に切り替えています。 -11EAGAIN に対応しますが、それをトリガーする特定のコードは errno だけでは判断できません。

その時点のデバイス統計はまだすべて 0 でした。

1
2
3
4
5
write_io_errs    0
read_io_errs     0
flush_io_errs    0
corruption_errs  0
generation_errs  0

スペースのステータスがいっぱいではありません:

1
2
3
4
5
Device size:            12.73TiB
Device allocated:        4.95TiB
Device unallocated:      7.78TiB
Device zone unusable:   53.58GiB
Used:                    4.88TiB

この一連の証拠は、通常のメディア I/O エラーやディスク全体の ENOSPC ではなく、ゾーン化された Btrfs 内部書き込み、チャンク割り当て、またはトランザクション ロジックの異常を支持します。ただし、最初のエラーと対応するソース コードを完全に分析しない限り、原因が特定のパッチにあるとは断言できません。

強制読み取り専用後の正しい処理

試しないでください:

1
2
3
4
sudo mount -o remount,rw /mnt/disk1
sudo btrfs balance start /mnt/disk1
sudo btrfs filesystem sync /mnt/disk1
sudo btrfs check --repair /dev/sda

まず書き込みタスクを停止します。

1
2
3
4
sudo pkill -TERM -x rsync
sudo pkill -TERM -x rsnapshot

pgrep -af 'rsync|rsnapshot|btrfs balance|btrfs scrub'

失敗の前後に完全なログを保存します。実際にトランザクションを中止させる最初のエラーは、forced readonly より数十行前に表示される場合があります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
sudo journalctl -k -b \
  --since "2026-07-24 17:20:00" \
  --until "2026-07-24 17:35:00" \
  > /root/btrfs-abort-2026-07-24.log

sudo dmesg -T \
  > /root/dmesg-btrfs-abort-2026-07-24.log

sudo smartctl -x /dev/sda \
  > /root/smart-sda-2026-07-24.log

マウント オプションを確認します。

1
findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /mnt/disk1

そこに ro が表示されるはずです。次に、アンインストールして通常どおり再起動します。

1
2
3
cd /
sudo umount /mnt/disk1
sudo reboot

ビジーというメッセージが表示された場合:

1
sudo fuser -vmM /mnt/disk1

アンインストールする前に、リストされている通常のユーザー プロセスを停止してください。

コピーが未完了でないか確認する

トランザクションが中止される前に書き込まれたデータの一部を直接完全なバックアップと見なすことはできません。表示される可能性があるもの:

  • ファイルはまだ作成されていません。
  • ファイルの長さが不完全です。
  • データは書き込まれますが、ディレクトリ エントリまたはタイムスタンプはコミットされていません。
  • 最後のトランザクションでの変更はロールバックされます。

したがって、ソースディスクは保持しておく必要があります。安定した環境に切り替えてマウントを再読み取りおよび書き込みした後、元の rsync を使用して以下を完了します。

1
2
3
4
sudo ionice -c2 -n7 nice -n 15 \
rsync -aHAX --info=progress2 \
  /来源目录/ \
  /mnt/disk1/目标目录/

次に、検証モードを使用して以下を検証します。

1
2
3
rsync -aHAXnc \
  /来源目录/ \
  /mnt/disk1/目标目录/

出力がない場合は、rsync が更新する必要のあるものが何も見つからなかったことを意味します。

カーネル ソリューション: まずテストと長期使用を区別する

同じマシン、同じ 7.0.0-28-generic、同じ HC620 が連続して出現しています。

  1. btrfs-cleaner はトランザクション スレッドでロックされています。
  2. error -11、トランザクションは中止され、強制的に読み取り専用になります。

したがって、このカーネルを使用してテラバイト単位のデータをこのディスクに読み書きすることは今後は行われません。次の 3 つのルートが議論されました。

行き方 目的 制限事項
Ubuntu 26.04 + 7.1 メインライン 新しいアップストリーム カーネルが障害を軽減するかどうかを判断します。 Ubuntu 以外の運用サポート カーネル、特定の修正は確認されていません。
Ubuntu 24.04 + 6.8 GA 7.0 でリグレッションが発生するかどうかを判断する。長期サポートの方が良い ゾーン化された Btrfs コードは古いです。
Ubuntu 24.04 + 6.17 短期比較テスト ゾーン再利用動作 サポート サイクルが終わりに近づいているため、長期間の無人操作には適していません。

ここで最も重要なことは、最大のバージョン番号を追求することではなく、次のことです。

  • ブート可能な古いカーネルを保持します。
  • GRUB ブートは初回のみ 1 回のみ実行してください。
  • 最初に読み取り専用でマウントします。
  • 100 から 200 GiB まで段階的にテストします。
  • 「3TB を削除した後すぐに 3TB を書き込む」は直接再現されなくなりました。

Ubuntu 24.04 6.8 GA で確認済み

Ubuntu 24.04 パッケージを既存の Ubuntu 26.04 と混合しないでください。より安全な方法は、別の SSD に Ubuntu Server 24.04 をインストールし、テストのために HC620 データ ディスクをマウントすることです。

6.8 GA メタパッケージをインストールして保持します。

1
2
3
sudo apt update
sudo apt install --install-recommends linux-generic-6.8
sudo reboot

システムとカーネルを確認します。

1
2
3
4
5
cat /etc/os-release
uname -r

dpkg -l | \
grep -E '^ii +linux-(generic|image-generic|headers-generic)(-6\.8)? '

重要なのは、uname -r6.8. で始まり、特定のパッチ バージョンを永続的にハードコーディングしないことです。

この記事の過去のバージョンをコピーする代わりに、現在のリポジトリをクエリします。

1
2
3
4
apt-cache policy \
  linux-generic-6.8 \
  linux-generic \
  linux-generic-hwe-24.04

テストの対象が GA 6.8 である場合は、linux-generic-hwe-24.04 によってシステムを別の HWE コア ラインに戻さないでください。

Ubuntu 24.04 6.17 での短期テスト

まず、現在のリポジトリでパッケージが引き続き提供・保守されているか確認します。

1
2
3
4
5
sudo apt update

apt-cache policy \
  linux-generic-6.17 \
  linux-image-generic-6.17

パッケージがまだ利用可能であることを確認したら、明示的にインストールします。

1
2
sudo apt install --install-recommends linux-generic-6.17
sudo update-grub

確認書類:

1
ls -lh /boot/vmlinuz-6.17.0-*-generic

初回のみ1回のみ起動してください。以下の完全なバージョンは、実際にマシンにインストールされているバージョンに置き換える必要があります。

1
2
3
4
5
sudo grub-reboot \
  'Advanced options for Ubuntu>Ubuntu, with Linux 6.17.0-xx-generic'

sudo grub-editenv - list
sudo reboot

再起動後の確認:

1
uname -r

このカーネルを強制インストールするために 24.04 Noble リポジトリを Ubuntu 26.04 に追加しないでください。追加しないと、ファームウェア、DKMS、initramfs、およびその後の apt メンテナンスの問題が発生する可能性があります。

7.1 メインラインをテストする場合の境界

Mainline パッケージは、「新しいアップストリーム カーネルによって障害の動作が変化するかどうか」を検証するのに適しており、公式の Ubuntu 製品カーネルと同等ではありません。インストール前に確認する必要があります:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
. /etc/os-release
echo "$PRETTY_NAME  codename=$VERSION_CODENAME"

dpkg --print-architecture
df -h /boot /

sudo apt update
sudo apt install -y mokutil
mokutil --sb-state
dkms status

セキュア ブートが有効になっている場合、重要な DKMS モジュールが存在する場合、またはサーバーに帯域外コンソールがない場合、テストのリスクは大幅に増加します。特定のバージョン、ファイル名、チェック値は現在の Ubuntu Mainline Kernel Archive から再取得する必要があり、期限切れのダウンロード アドレスはコピーしないでください。

現在のブート可能なカーネルを保持し、GRUB 経由で新しいカーネルを一度にブートします。起動後の確認:

1
2
3
4
5
6
7
8
uname -r
systemctl --failed
ip addr
ip route
dkms status

sudo dmesg -T | \
grep -iE 'btrfs|hung task|blocked for more|I/O error|ata|medium error|uncorrect'

新しいカーネルの最初のマウントとテスト

6.8、6.17 をテストする場合でも、カーネルを更新する場合でも、まず noauto/etc/fstab に保持し、起動後に読み取り専用でマウントします。

1
2
3
4
5
6
7
sudo mount -o ro /dev/sda /mnt/disk1

sudo journalctl -k -b | \
grep -iE 'btrfs|error|warning|abort|readonly|hung|blocked|I/O error'

sudo btrfs device stats /mnt/disk1
sudo btrfs filesystem usage /mnt/disk1

新しいエラーが発生しなくなった後:

1
2
3
4
sudo umount /mnt/disk1
sudo mount /dev/sda /mnt/disk1

findmnt -no SOURCE,TARGET,FSTYPE,OPTIONS /mnt/disk1

段階的なテスト:

1
2
3
4
5
6
写入 100~200GiB
→ btrfs filesystem sync
→ 检查日志和 D 状态
→ 删除 100~200GiB
→ 等待并再次检查
→ 再写入下一批

小さなバッチが通過したからといって、すぐにテラバイト規模の圧力が「修正」されたことを意味するわけではありません。信頼性を高めるには、少なくとも複数のラウンド、大量のデータ、長い実行時間が必要です。

Btrfs を再フォーマットするかどうか

再フォーマットするとファイル システムがクリーンになる可能性がありますが、カーネル ゾーン パスの問題だけを解決することはできません。どちらの例外も実行時にブロック グループ、ゾーン、トランザクション パスで発生し、デバイス統計にはメディア エラーはありませんでした。

ファイル システムの再構築は、次の場合にのみ意味があります。

  • btrfs check --readonly 明示的な構造エラーが見つかりました。
  • スクラブでは修復不可能な検証エラーが発生し続けます。
  • 正常にマウントできない、または生成エラーが発生し続ける。
  • データ/メタデータ プロファイルを調整することが決定されました。
  • ファイルシステムを置き換える準備をします。

再構築する場合でも、フォーマットを試行錯誤のコマンドとして扱うのではなく、まず別の検証可能なバックアップを完了してください。

Btrfs と F2FS のどちらを選択するか

F2FS は、今回表示される Btrfs 固有の呼び出しパスをバイパスできます。

1
2
3
4
5
btrfs_delete_unused_bgs
btrfs_remove_chunk
btrfs_zone_finish_one_bg
Btrfs chunk allocation
Btrfs transaction commit

しかし、それは「問題のない」解決策ではありません。 F2FS には、GC、セグメント移行、ゾーン リセット、停電復旧、ファイル システム修復にもリスクがあります。大規模な削除の直後に大規模な書き込みを行うと、依然として長いフォアグラウンド GC 遅延が発生する可能性があります。

この 2 つの間の主なトレードオフは次のとおりです。

プロジェクト Btrfs ゾーン F2FS
ファイルデータのチェックサム はい 通常、同等のエンドツーエンド データ チェックサムはありません。
スクラブ はい Btrfs スタイルのスクラブなし
スナップショット はい Btrfs スタイルのスナップショットはありません
この障害パス 実際には 2 回トリガーされました Btrfs 固有のパスは回避できます。
バックグラウンド領域の再利用 ブロックグループ/ゾーンの再利用 セグメント GC/ゾーン リセット

HC620 が複数のバックアップのうちの 1 つにすぎない場合は、F2FS と外部パリティを使用できます。単一ディスクの Btrfs も F2FS も、それが唯一のコピーである場合には十分に安全ではありません。

F2FS を使用する場合は、SHA256 リストを別のディスクに保存できます。

1
2
3
4
5
6
cd /mnt/disk1

find backup_data -type f -print0 | \
sort -z | \
xargs -0 sha256sum \
  > /其他磁盘/backup_data.sha256

後で確認してください:

1
2
cd /mnt/disk1
sha256sum -c /其他磁盘/backup_data.sha256

ドライブ独自の ECC、不良セクターの再マッピング、SATA CRC は引き続き機能しますが、アプリケーション、メモリ、ファイル システム、コントローラー、ディスク間の完全なエンドツーエンド リンクをカバーするわけではありません。 Btrfs チェックサムとハードディスク ECC は補完的なものであり、重複する機能ではありません。

今回の障害から得た運用ルール

このトラブルシューティングの結果、次の実際的なルールが得られました。

  1. この HC620 の大規模な読み取りおよび書き込みを行うために 7.0.0-28-generic を使用しなくなりました。
  2. ソース データと少なくとも 1 つの独立したコピーを保持します。
  3. 最初にコピーして検証し、次にバッチで削除します。
  4. 数 TB の操作を 200 ~ 500 GiB のバッチに分割します。
  5. rsync、rsnapshot、スクラブ、一括削除、およびバランスは重複しません。
  6. D ステータスまたはハングタスク ログが表示されたら、すぐに書き込みを停止します。
  7. 読み取り専用を強制した後、再マウント、rw を強制しないでください。
  8. btrfs check --repair を使用してやみくもに試行しないでください。
  9. テスト カーネルはロールバック項目を保持し、読み取り専用マウントで開始する必要があります。
  10. 長期的な信頼性は、まず複数のコピーを作成し、次にファイル システムを選択することによって実現されます。

障害チェーン全体は次のように要約できます。

1
2
3
4
5
6
7
数 TB 删除
→ zoned 无效空间和后台回收增加
→ 数 TB 新写入与 chunk/zone 管理交叠
→ 第一次:btrfs-cleaner 锁等待,事务线程阻塞
→ 重启后暂时恢复,scrub 与设备计数未见错误
→ 再次大量写入
→ 第二次:transaction -11,中止并 forced readonly

この一連の結果は、現在の「HC620 + ゾーン化された Btrfs + 7.0.0-28 + CLOS」の組み合わせが大規模な無人タスクの継続には適していないことを示すには十分ですが、すべての HC620、ゾーン化されたすべての Btrfs、またはすべての 7.0 カーネルに同じ問題があることを証明するには十分ではありません。

参考文献