MENU

溶けかけてるうさぎ HP GALLERY BLOG TOP RECENT ARTICLES POPULAR ARTICLES ABOUT THIS BLOG

CATEGORY

大学 (137) 仕事 (27) 航空宇宙 (106) 写真 (79) 旅行 (33) 飯・酒 (17) コンピュータ (128) その他 (48)

TAG

ARCHIVE

RECENT

【自宅サーバー】10年以上使ってきた HDD の状況確認と復旧作業 AI がここまで身近になり思うこと 【自宅サーバー】VPN サーバーの更新 必要範囲で切り抜くことで衛星データを高速にダウンロード ふと 博士号について

【自宅サーバー】10年以上使ってきた HDD の状況確認と復旧作業

事象発生日:2026-10-25

記事公開日:2026-10-27

アクセス数:11

10 年ほど使ってきた自宅サーバーをシステム用 HDD の交換に合わせてクリーンインストールしました.

そのついでに自宅サーバー 2 台分の HDD の SMART を確認したところ,長年ほぼ不具合なしで動いていることに感心しつつも,気になる点や読めないセクタが見つかったりしました.

それらの設定見直しと,読めないデータへの対処の備忘録です.

自宅サーバーのクリーンインストール

最近,セキュリティ事情が厳しくなっていることなどもあり,集中的に自宅サーバー群のメンテナンスをしています.

自宅サーバーのうち,最も古いマシン(サーバー A とする)は,2016 年 5 月に構築したもので,それから 10 年以上ほぼ絶え間なく動き続けています.

 

このサーバーなのですが,10 年以上様々な用途で使ってきており(実はこのブログもこのサーバー上で動いている),長年の試行錯誤や実験の残骸が残ってしまっていることもあるので,きれいさっぱりクリーンインストールさせることにしました.

HDD 6 台の SMART を確認

今回更新するサーバーには 3 台の HDD が搭載されています.

2 台はサーバー構築時から,もう 1 台は 2018 年 1 月に追加したものです.

 

また,隣で動いている 2020 年 4 月に構築した別サーバー(サーバー B とする)にも,3 台の HDD が搭載されており,今回はこれも合わせて計 6 台の HDD の状況を確認しました.

 

以下はメンテナンス前の HDD の記録です.

HDD通電時間ヘッド退避回数不良セクタ等用途
TOSHIBA DT01ACA200 (2 TB)85,297 時間284 回0 / 0 / 0A: システム
Seagate ST2000DM001 (2 TB)約 85,000 時間 ※361 回0 / 0 / 0A: 録画・共有
WD WD40EZRZ (4 TB)75,801 時間56,774 回0 / 0 / 0A: ファイル共有
WD WD20EZRZ (2 TB)57,178 時間5,200,245 回0 / 5 / 4B: システム
WD WD60EZAZ (6 TB)57,159 時間51,877 回0 / 0 / 0B: 録画・共有
Seagate ST6000DM003 (6 TB)57,222 時間7,802 回0 / 0 / 0B: ファイル共有

なお,表の備考は,

「不良セクタ等」は,代替処理済み / 保留中 / オフライン訂正不能の値です.A・B は 2 台のサーバーを表します.
ST2000DM001 の通電時間(※)は,表示に不整合があるため,Head_Flying_Hours の 85,304 時間を参考にした推定です.

です.

 

今回取り外した旧システム用の DT01ACA200 は,10 月 22 日時点で 85,297 時間でした.約 9.7 年分です.

メンテナンスや引っ越しなどで電源を落としていた時間もあるため,10 年には少し届いていないですね.

WD40EZRZ も約 8.7 年分,サーバー B の 3 台もそれぞれ約 6.5 年分と,どれもだいぶ長いこと動いています.

 

個人的にすごいなぁ(というか,頑張ったなぁ)と思うのは,これが温度も湿度も電源も何も管理していない自宅での運用だったことです.

人間が家にいれば空調が効いていますが,コロナ禍を除きほぼリモートをしていないことや,ここ数年は仕事の都合で 3 週間連続で出張しているようなこともしばしばありました.

空調の効いていない夏場などは,なかなかの劣悪な環境になっていたと思います.

 

なお,SMART の全体判定は 6 台とも PASSED でした.

ただし,細かく見ると気になる項目はあります.

ST2000DM001 には過去の ATA エラーが 2 件記録されていました.

どちらもログ上の通電時間が 43,186 時間のときのもので,同じセクタ位置を示しています.

一方は UNC(訂正不能な読み取りエラー),もう一方は WP(書き込み保護を示す表示)でしたが,当時の詳しい原因までは OS 側のログが残っておらず分かりません.

 

さらにサーバー B のシステム HDD である WD20EZRZ には,

ヘッド退避回数が約 520 万回と,定格の 17 倍を超えていた
代替処理の保留中として記録されたセクタが 5 つあった

という見過ごせない記録がありました.

 

次から,この 2 つの問題の対処記録を残します.

システム HDD のヘッド退避回数の抑制

まず気になったのが,サーバー B のシステム用 HDD の WD20EZRZ のヘッド退避回数です.

SMART の Load_Cycle_Count が約 520 万回になっていました.

HDD のメーカー仕様に記載されたロード/アンロード回数は 30 万回なので,その約 17 倍で,さすがに多すぎです.

 

この HDD には,一定時間アクセスがないとヘッドを退避させる idle3 タイマーという設定があり,今回の HDD ではこれがデフォルト値の 8 秒になっていました.

システムログなど短い間隔で少しずつアクセスが発生するような使い方だと,ヘッドを退避させては戻す,という動作を繰り返してしまいます.

実際,設定変更前に観測したところ,28 分間で 39 回,1 時間あたり約 84 回のペースで増えていました.

 

もともとは省電力のための設定のようでした.

デスクトップ向け HDD をサーバーのシステム用に使うことの弊害をきちんと認識できていなかったのが反省ポイントです.

 

今回は,idle3-tools の idle3ctl を使い,idle3 タイマーを 300 秒に変更しました.

サーバー A に今回新しく取り付けた交換後のシステム用 HDD も同じ WD20EZRZ で,こちらも短時間に退避回数が増えていたため,同様に変更しました.

 

設定変更後,10 月 27 日に再確認した結果は次のとおりでした.

HDD電源を入れ直した直後約 58 時間後増加回数
A: 交換後のシステム用1,516 回1,516 回0 回
B: システム用5,200,352 回5,200,403 回51 回

サーバー B は,この間の平均では 1 時間あたり約 0.9 回となり,設定変更前に観測した約 84 回と比べると,かなり落ち着きました.

今後,通常運用に戻してしばらく様子を見ることにします.

なお,データ用の WD 4 TB と 6 TB は,もともと退避回数の増加が 1 時間に 1 回未満だったため,設定を変えていません.

保留中のセクタを調査し,読めないファイルを修復

もう 1 つの問題は,同じ WD20EZRZ に代替処理保留中のセクタが 5 つあったことです.

こちらは実際に読めない箇所があったので,場所を調べて対処しました.

エラーログに記録された場所の調査

最初に確認した値は,次のとおりでした.

Reallocated_Sector_Ct    0    : 代替処理済み
Current_Pending_Sector   5    : 保留中
Offline_Uncorrectable    4    : オフライン訂正不能

さらに過去の ATA エラーログにも,訂正不能な読み取りエラー UNC が 5 件残っていました.

 

エラーの発生したディスク上の位置 (LBA) から,ファイルシステムのブロック番号を計算し,debugfs でどのファイルに属するかを調べました.

すると,ログに残っていた 5 個所は,すべて /swap.img の中でした.

 

そこで,メモリーの空き容量を確認してから swap を停止し,既存の swap ファイルを残したまま全体をゼロで上書きしました.

その後,ディスクから全体を読み戻せることを確認し,swap を再初期化して有効に戻しました.

ファイルを削除して作り直すと,別の場所に割り当てられる可能性がありますが,今回は問題のあった場所に書き込みたかったので,既存のファイルを上書きし,前後でディスク上の配置が変わっていないことも確認しています.

 

この作業で,保留中のセクタは 5 から 4 に減りました.代替処理済みセクタは 0 のままです.

ただし,残りの 4 個所がどこにあるのかは,過去のエラーログだけでは分かりませんでした.

過去にエラーが起きた場所が,現在も保留中とは限らない,ということのようです.

long self-test による不良セクタの探索

残りの不良セクタの場所を調べるため,バックアップを取ってから long self-test を実行しました.

以下のコマンドは,実際に行った作業から抜粋・簡略化したものです.

$ disk=/dev/disk/by-id/XXXXXXXXXXXXXXXX

# 長時間の自己テストを開始
$ sudo smartctl -t long "$disk"

# 進行状況と結果を確認
$ sudo smartctl -c "$disk"
$ sudo smartctl -l selftest "$disk"

テスト開始時には約 277 分かかると表示されましたが,結果を確認すると,読み取りエラーで終了していました.

# Test_Description  Status                    Remaining  LifeTime(hours)  LBA_of_first_error
Extended offline    Completed: read failure   90%        57182            14032584

最初に見つかったのは LBA 14,032,584(先頭から約 7.2 GB の位置)で,この結果だけでは,その先にも読めない場所があるかどうかは分かりません.

そこで,読めなかった物理セクタの次から末尾までを,範囲指定の selective self-test で調べました(今回の HDD では,4096 バイトの物理セクタ 1 個に 512 バイト単位の LBA が 8 個分含まれる.エラーが出た位置は物理セクタの先頭だったため,その物理セクタを飛ばした次の位置,つまり LBA に 8 を加えた位置からテストを再開している).

# 最初に読めなかった物理セクタの次から調べる
sudo smartctl -t select,14032592-max "$disk"

# 終了後に結果を確認
sudo smartctl -l selftest "$disk"

またエラーで終了したら,その場所を記録して次から読む,ということを繰り返した結果,次の 4 箇所のエラーが見つかりました.

$ sudo smartctl -l selftest "$disk"
# 1  Selective offline   Completed without error       00%     57201         -
# 2  Selective offline   Completed: read failure       90%     57195         14217304
# 3  Selective offline   Completed: read failure       90%     57195         14041568
# 4  Selective offline   Completed: read failure       90%     57195         14039280
# 5  Extended offline    Completed: read failure       90%     57182         14032584

セクタ位置から該当するファイルの特定

次に,読めなかった場所が何に使われているかを調べます.

今回のファイルシステムは /dev/sda2 上の ext4 で,パーティションの開始位置は 1,050,624 セクタ,ファイルシステムのブロックサイズは 4096 バイトでした.

$ cat /sys/block/sda/sda2/start
1050624
$ sudo tune2fs -l /dev/sda2 | grep 'Block size'
Block size:               4096

LBA はディスク全体の先頭から数えた位置なので,パーティションの開始位置を引いてからファイルシステムのブロック番号に直します.

例えば LBA 14039280 なら,ブロック番号は (14039280 - 1050624) / 8 = 1623582 となります.

その結果をもとに,debugfs の icheck で inode を調べ,ncheck でファイル名を引きます.

実行結果はこのような感じです.

$ sudo debugfs -R "icheck 1623582" /dev/sda2
debugfs xx.xx.xx
Block   Inode number
1623582 52698848
$ sudo debugfs -R "ncheck 52698848" /dev/sda2
debugfs xx.xx.xx
Inode   Pathname
52698848        /usr/lib/x86_64-linux-gnu/libboost_wave.so.xx.xx.xx

調べた結果は次のとおりでした.

LBA使われていた場所
14,032,584空き領域
14,039,280/usr/lib/x86_64-linux-gnu/libboost_wave.so.xx.xx.xx
14,041,568/usr/bin/libtoolize
14,217,304空き領域

4 箇所とも,約 94 MB の範囲に固まっていました.

ファイルの領域と重なっていたものも,普段使わなさそうなファイルだったため,これまで気づかなかっただけのよう?です.

破損したファイルの復旧

幸い,不良セクタによって破損した 2 つのファイルは,どちらも Ubuntu のパッケージに含まれるファイルでした.

そこで,インストール済みのものと同じバージョンのパッケージを取得し,その内容を使って読めない部分だけを書き直しています.

ざっくり,次のような手順です.

対象ファイルが使用中でないことと,ディスク上の配置を確認する.
同じバージョンのパッケージからファイルを取り出し,チェックサムを照合する.
各ファイルの読めない 4,096 バイトのブロックだけを正しいデータで上書きする.
キャッシュを通さずにファイル全体を読み戻し,パッケージの内容と一致することを確認する.
修復した範囲の selective self-test を実行する.

 

具体的なコマンドを簡単に記録しておきます(以下は libtoolize 側を例にしたコマンド).

 

まず,インストール済みのものと同じバージョンのパッケージを取得し,展開したファイルのサイズと MD5 がパッケージ管理情報に記録された値と一致することを確認しました.

# インストール済みのバージョンを調べ,同じものを取得
$ pkg=libtool
$ version=$(dpkg-query -W -f='${Version}' "$pkg")

$ work=$(mktemp -d)
$ cd "$work"
$ apt-get download "$pkg=$version"

# パッケージを展開
$ dpkg-deb -x ./*.deb extracted

# 正しい内容の照合に使用
$ dpkg-query --control-show "$pkg" md5sums | grep ' usr/bin/libtoolize$'
$ md5sum extracted/usr/bin/libtoolize

swap ファイルのときと同様に問題のあった場所のみに書き込むために,単にパッケージを再インストールするのではなく,既存ファイルの読めないブロックだけを書き直しました.

書き込み前には,対象ファイルが使用中でないこととパッケージの更新処理が動いていないことを確認しています.

また,filefrag でファイル内の位置とディスク上の位置を照合しました.

$ sudo lsof /usr/bin/libtoolize
$ sudo filefrag -v -b4096 /usr/bin/libtoolize

libtoolize の読めない部分は,(ファイル先頭を 0 とした)28 番目の 4096 バイトのブロックでした.そこで,正常なファイルの同じ位置から 1 ブロックを取り出し,上書きしました.

sudo dd \
  if="$work/extracted/usr/bin/libtoolize" \
  of=/usr/bin/libtoolize \
  bs=4096 skip=28 seek=28 count=1 \
  iflag=fullblock oflag=direct \
  conv=notrunc,nocreat,fsync

conv=notrunc はファイルの残りを切り詰めないため,nocreat は出力先が存在しない場合に新規作成しないための指定です.

もう一方のライブラリーも同様に,30 番目のブロックだけを書き直しました.実際の作業では,ファイルの inode やサイズの確認,更新日時の復元も行っています.

 

読み戻したファイルのチェックサムは一致し,dpkg --verify でも差分は出ませんでした.

修復した範囲の selective self-test も,Completed without error で完了し,問題のあったブロックも正しく読み取れることを確認しました.

対応後の状態

SMART の値の変化は次のとおりでした.

時点代替処理済み保留中オフライン訂正不能
作業前054
swap ファイルの書き直し後044
2 つのファイルの修復後024

保留セクタは 5 → 4 → 2 と減りました.

代替処理済みセクタは増えておらず,書き直した箇所は代替処理なしで再び読み取れる状態になっています.

残りの 2 個所は空き領域だったため,今回はそのままにしました.

その領域にファイルを書き込もうとした時に,正常に書き込まれるか,代替処理が発生する可能性があります.

 

オフライン訂正不能の 4 という値も残っています.

これは以前の検査結果が残っている可能性がありますが,詳細は不明です.

 

なお,ヘッド退避回数の多さが今回の読み取り不良の原因だったかまでは分かりません.

修復したファイルが読めることを確認できたので,ディスクの交換も含めて今後の扱いを考えることにします.

おわりに

サーバーのクリーンインストールのついでに HDD の状態を確認しただけだったのですが,結構なボリュームの作業となってしまいました.

また,普通にサーバー B のシステムディスクの状態が不安なこともわかったので,定期的に状況を確認することは大事だなと改めて気付かされました.

 

データは突然吹っ飛びますからね.

関連記事

コメントを投稿

名前

Email (※公開されることはありません)

コメント