RAID5なbtrfsのHDDをreplaceした話
btrfsで作ったディスクアレイのHDDを交換したので、やり方のメモです。 前に書いた完全にディスクが死んでいる場合の記事とは違って、今回は一応マウント出来る状態での交換です。
故障の発見 / 状況を確認する
なんだかやたらとファイルサーバへのアクセスが遅くなっていたので調べてみたところ、dmesgに以下のようなエラーが大量に記録されていました。
$ sudo dmesg
[17415.702324] BTRFS info (device sdf): read error corrected: ino 1 off 60428511150080 (dev /dev/sdd sector 3575050240)
[17415.718786] BTRFS info (device sdf): read error corrected: ino 1 off 60428511154176 (dev /dev/sdd sector 3575050248)
[18003.357383] BTRFS warning (device sdf): sdf checksum verify failed on 60428489015296 wanted 65315BEF found CDF7F87E level 0
[18112.286563] BTRFS warning (device sdf): sdf checksum verify failed on 60428489015296 wanted 65315BEF found CDF7F87E level 0
[29995.452458] BTRFS error (device sdf): bad tree block start 7611175298055105740 60427922653184
[29995.465097] BTRFS error (device sdf): bad tree block start 7611175298055105740 60427922866176
うーん、/dev/sdd
が死にそう。
device stats
にもエラーが記録されていました。
$ sudo btrfs device stats /mnt/data
... 省略 ...
[/dev/sdd].write_io_errs 0
[/dev/sdd].read_io_errs 0
[/dev/sdd].flush_io_errs 0
[/dev/sdd].corruption_errs 58650
[/dev/sdd].generation_errs 0
... 省略 ...
死にそうではあるのですが、degradedオプションを付けなくてもマウント出来る状態です。
btrfs scrub
とかやっても一応読めている(でもdmesgに大量にエラーが出る)みたいでした。
瀕死だけど死んでない。
この「degraded付けなくてもマウント出来る」状態であれば、この記事の方法を使うことが出来ます。
もしもdegradedオプションを付けないとエラーが出てマウント出来ないような場合は、以下の記事の方法を試してみてください。
btrfsで作ったRAIDのHDDが壊れた。ので、交換した。
新しいHDDを接続する
新しいHDDが届いたら、通常通りPCに接続します。
今回はreplaceを使うので、壊れかけの古いHDDも繋いだままにしておきます。
古いHDDから新しいHDDにデータをコピーする
接続出来て動作することが確認出来たら、以下のコマンドでreplaceを開始します。
$ sudo btrfs replace start /dev/sdd /dev/sdg /mnt/data
ここでは、/dev/sdd
が古いディスク、/dev/sdg
が新しいディスクで、/mnt/data
がマウント先になっています。
状況を確認しながら待つ
以下のコマンドで進捗状況を確認することが出来ます。
$ sudo btrfs replace status /mnt/data
0.0% done, 0 write errs, 0 uncorr. read errs
めちゃくちゃ時間が掛かるので、のんびり待つと良いと思います。
といってもadd
してremove
する時よりも速いし進捗も見やすいので、比較的待つのは辛くない感じがあります。
コピーが完了すると、replace status
の結果が以下のように変わります。
$ sudo btrfs replace status /mnt/data
Started on 13.Jun 19:17:06, finished on 15.Jun 23:25:21, 0 write errs, 0 uncorr. read errs
これで、HDDの置き換えは完了です。 古いHDDを外して処分しましょう。
エラーカウントをリセットしておく
今回の例だと/dev/sdd
を交換しましたが、これだけだとdevice stats
に記録されたエラーはそのままになっています。
そうなると今後エラーを見つけられなくて困るので、カウントをリセットしておきましょう。
$ sudo btrfs device stats --reset /mnt/data
... 省略 ...
[/dev/sdd].write_io_errs 0
[/dev/sdd].read_io_errs 0
[/dev/sdd].flush_io_errs 0
[/dev/sdd].corruption_errs 58650
[/dev/sdd].generation_errs 0
... 省略 ...
もう一回stats
を見てみると、綺麗に消えているはずです。
$ sudo btrfs device stats /mnt/data
... 省略 ...
[/dev/sdd].write_io_errs 0
[/dev/sdd].read_io_errs 0
[/dev/sdd].flush_io_errs 0
[/dev/sdd].corruption_errs 0
[/dev/sdd].generation_errs 0
... 省略 ...
これで次にエラーが起きたときも分かりやすくて安心。
容量の大きいHDDに交換した場合
HDDの交換が完了した後でdevice usage
を見てみると、以下のようになっていました。
$ sudo btrfs device usage /mnt/data
... 省略 ...
/dev/sdf, ID: 6
Device size: 2.73TiB
Device slack: 0.00B
Data,RAID10: 2.68TiB
System,RAID1: 32.00MiB
Unallocated: 47.49GiB
/dev/sdg, ID: 7
Device size: 5.46TiB
Device slack: 1.82TiB
Data,RAID10: 3.57TiB
Metadata,RAID1: 14.00GiB
System,RAID1: 64.00MiB
Unallocated: 53.96GiB
ずっと繋いでいる/dev/sdf
(3TB)はDevice slack
が0Bなのですが、今回追加した/dev/sdg
(4TBから6TBに増やした)はDevice slack
が2TBになっています。
単純に容量の大きいストレージを繋いだだけだと、余剰扱いになってしまって使ってくれないみたいです。
なので、以下のコマンドでフルに使って良いことをbtrfsに伝えます。
$ sudo btrfs filesystem resize 7:max /mnt/data
Resize '/mnt/data' of '7:max'
ここで書いている7
はさっきのdevice usage
で見れるIDの番号です。
このコマンドはわりとすぐ終わります。 終わったら、以下のような感じでフルに使えるようになっているはず。
$ sudo btrfs device usage /mnt/data
... 省略 ...
/dev/sdf, ID: 6
Device size: 2.73TiB
Device slack: 0.00B
Data,RAID10: 2.68TiB
System,RAID1: 32.00MiB
Unallocated: 47.49GiB
/dev/sdg, ID: 7
Device size: 5.46TiB
Device slack: 0.00B
Data,RAID10: 3.57TiB
Metadata,RAID1: 14.00GiB
System,RAID1: 64.00MiB
Unallocated: 1.87TiB
この時点ではデータが偏って配置されてしまっているので、最後にbalance
を実行してあげましょう。(これが時間掛かる…)
$ sudo btrfs balance start --bg --full-balance /mnt/data
これも、適当に状況を見ながら待ちます。
$ sudo btrfs balance status /mnt/data
Balance on '/mnt/data' is running
1 out of about 3674 chunks balanced (2 considered), 100% left