/var を SSD から HDD に移行する案を検討した

前回は SSD 書き込み削減の案のひとつとして SSD のスワップ領域を削除した。今回はこれに続いて、ルートファイルシステムを SSD 上に置き、データ領域を HDD 上に逃がすという構成を前提に、SSD の書き込みをさらに抑制する方法を検討した。本稿では、/var/log、/var/cache、/var/tmp を HDD 側に移動して bind mount で運用する案を具体的手順まで詰め、その安全性、効果、リスク、および最終判断を記録する。最終的な結論として、この構成は採用しない。


目的と背景

目的は SSD の書き込み頻度を抑制し、結果として SSD の寿命を延ばすことにある。現在の環境は以下のとおりである。

  • ルート (/) は SSD 上に存在する。
  • HDD のうちメインとなるディスクは /mnt/disk1 にマウント済みである。
  • /home と /opt はすでに HDD 側に移設済みであり、ルート配下からシンボリックリンクしている。

今回の検討では、日常的に書き込みが多いと考えられる /var/log、/var/cache、/var/tmp を HDD 配下 (/mnt/disk1) に移動し、bind mount によってマウントポイントを差し替えることで SSD への書き込みを極小化する案を評価した。


bind mount を使う理由

/home と /opt は HDD 側に移し、ルート上にはシンボリックリンクだけを残すという形にしても大きな問題は起きない。これはそれらのディレクトリがシステムのブート初期には必須ではないからである。

  • /home はユーザのホームディレクトリであり、主にログイン後にアクセスされる領域である。多少マウントが遅延してもブートシーケンスに致命的な影響は出ない。
  • /opt は追加アプリケーションの格納先である。多くのサービスはブート完了後に /opt 以下のパスを参照するため、こちらも遅延マウント許容範囲といえる。

これに対して /var は事情が異なる。/var 以下はシステムブートのかなり早い段階から読み書きされる領域であり、次のようなコンポーネントが依存している。

  • systemd-journald は起動直後から /var/log/journal に永続ログを書き込もうとする。
  • udev や初期化スクリプトは /var/tmp を前提に一時情報を保持する。
  • dpkg や apt は /var/lib や /var/cache/apt に対して状態情報やキャッシュを書き込みにいく場合がある。

/var 自体、あるいは /var/log, /var/cache, /var/tmp をシンボリックリンクにしてしまうと、リンク先である HDD 側のマウントが間に合わなかった場合に「そのディレクトリが存在しない」という扱いになる。この場合、ジャーナル書き込みやデバイス初期化が失敗し、最悪ブート不能や degraded 状態での起動となるリスクがある。

bind mount はこれを回避できる。bind mount では、ルートファイルシステム上に /var/log などのディレクトリそのものは残しつつ、中身だけを別の場所 ( /mnt/disk1/var/log など) に差し替える。これにより、ブート時点では /var/log 等は常にディレクトリとして存在するため、初期化時の参照先としては有効なまま維持される。通常稼働に入った時点では bind mount が上書きされ、実際の書き込みは HDD 側に逃がされる、という形になる。


想定していた移行手順

以下は実際に適用するために整理した手順である。結果として採用しないが、作業の分解は記録として残す。

1. HDD 側に受け皿ディレクトリを作成する

sudo mkdir -p /mnt/disk1/var/{log,cache,tmp}
sudo chown root:root /mnt/disk1/var/{log,cache,tmp}
sudo chmod 0755 /mnt/disk1/var/log
sudo chmod 0755 /mnt/disk1/var/cache
sudo chmod 1777 /mnt/disk1/var/tmp

/var/tmp は sticky bit (1777) を維持する必要がある。ここを壊すとセキュリティリスクになる。

2. システムの自動処理を停止する

移行中の書き込み競合を避けるため、cron などの自動処理やログ書き込みサービスを止める。

sudo systemctl stop cron
sudo systemctl stop rsyslog
sudo systemctl stop systemd-journald

cron は 5 分間隔や 1 日間隔のジョブから /var/log にログを吐く可能性がある。rsyslog と systemd-journald は /var/log 系に随時書き込むため停止対象とする。この状態では一時的にログが記録されない。

3. 既存データを HDD 側へコピーする

sudo rsync -aXS --exclude='*.lock' /var/log/   /mnt/disk1/var/log/
sudo rsync -aXS                 /var/cache/ /mnt/disk1/var/cache/
sudo rsync -aXS                 /var/tmp/   /mnt/disk1/var/tmp/

-aXS によりパーミッションや拡張属性を維持したままコピーする。/var/log のロックファイルは再生成可能なため除外している。

4. 元ディレクトリを退避し、空ディレクトリを再作成する

sudo mv /var/log   /var/log.bak
sudo mv /var/cache /var/cache.bak
sudo mv /var/tmp   /var/tmp.bak

sudo mkdir /var/log /var/cache /var/tmp
sudo chown root:root /var/log /var/cache /var/tmp
sudo chmod 0755 /var/log /var/cache
sudo chmod 1777 /var/tmp

ここで /var/log, /var/cache, /var/tmp は空のディレクトリとして復元される。この空ディレクトリが bind mount のマウントポイントになる。

5. bind mount を貼る

sudo mount --bind /mnt/disk1/var/log   /var/log
sudo mount --bind /mnt/disk1/var/cache /var/cache
sudo mount --bind /mnt/disk1/var/tmp   /var/tmp

確認には findmnt を使う。

findmnt /var/log
findmnt /var/cache
findmnt /var/tmp

これで /var/log などが /mnt/disk1/var/… に差し替わっていれば正しく bind されている。

6. /etc/fstab に恒久設定を追加する

/mnt/disk1/var/log   /var/log   none   bind   0   0
/mnt/disk1/var/cache /var/cache none   bind   0   0
/mnt/disk1/var/tmp   /var/tmp   none   bind   0   0

fstab に書くことで、再起動後も同じマウント関係が維持される。

7. 停止したサービスを再開する

sudo systemctl start systemd-journald
sudo systemctl start rsyslog
sudo systemctl start cron

復帰後の確認として logger コマンドを実行し、/mnt/disk1/var/log 側にログが記録されることを確認する。

logger "post-migration test log entry"
ls -l /mnt/disk1/var/log

8. バックアップディレクトリの処理

安定稼働を確認した後であれば、/var/log.bak などの退避ディレクトリを削除できる。ただし過去ログを監査用途で参照したい場合は数日程度保持しておく判断も残る。


/var/cache の munin キャッシュについて

/var/cache には munin が収集した監視データが保存される。このデータは RRD (Round Robin Database) 形式で保持される。

  • RRD は固定長のファイルを用意し、その固定サイズファイルの中の一部ブロックを更新し続ける方式である。ファイルをどんどん肥大化させるのではなく、過去データを一定容量にローテーションしながら保持する。
  • munin は監視対象ごとに RRD ファイルを持つ。1 ホストあたり数十ファイル程度になることが一般的である。
  • RRD の更新は 5 分ごとの収集サイクルなどで発生する。各データポイントごとに 8〜32KB 程度のブロックが部分的に書き換えられる。
  • 24 時間で見ると、こうした細かい部分上書きが積み重なっても総書き込み量は数百MB 程度に収まるケースが多い。

このように munin の場合、/var/cache 内の RRD は「固定長」「部分更新」「定期追記ではなく部分書き換え」という性質を持つ。これは SSD にとっては継続的な小規模ランダムライトに相当するが、後述する SSD の耐久性指標からみると依然として軽い部類に入る。


SSD の寿命評価

SSD の寿命は主に TTBW (Total Bytes Written) および DWPD (Drive Writes Per Day) で表現される。

  • TBW はその SSD が保証する総書き込み量で、たとえば 128GB クラスの一般的な SSD では 70〜150TB 程度が多いとされる。
  • DWPD は保証期間中に 1 日あたりドライブ全体を何回書き換えられるかという指標である。一般的なコンシューマ向け SSD では 0.3〜0.5 DWPD 程度が多い。

TBW を具体的に見る。仮に 100TB の TBW がある SSD を想定し、1 日あたり 10GB の書き込みを継続したとする。この場合、100TB / 10GB は 10,000 日、約 27 年に相当する。70TB の場合でも 7,000 日を超える。読み込みは TBW のカウントに含まれないので、読み取り負荷は無視できる。

実際の /var/log への書き込みは、カスタムのジョブが吐くログやシステムログが主であり、多くはテキストおよびローテーション済みのファイル追記である。/var/cache に関しては munin が 5 分周期で RRD を更新するが、これは RRD ファイルに対する 8〜32KB 程度の部分的な上書きであり、1 ホストあたり数十ファイルが対象になったとしても 24 時間あたり数百MB 程度の規模である。/var/tmp は一時ファイルの退避先だが、巨大連続書き込みが常時走るわけではない。

まとめると、これらをすべて SSD 上に置いたままでも、1 日あたりの総書き込み量はおおむね数GB〜10GB 程度のオーダーに収まる。このレベルの書き込み量では、128GB クラスの SSD の TBW (70〜150TB) を消費し切るまでに数十年かかる計算になる。つまり、/var/log や /var/cache (特に munin の RRD 更新) のような定常書き込みは、SSD の寿命にとって決定的な問題にはならないといえる。

さらに、現行の SSD はウェアレベリングとオーバープロビジョニングにより、実効寿命がカタログ値より長くなることが多い。これは、書き込みブロックがフラッシュメモリ全体に分散されるように制御されており、特定領域だけが極端に摩耗しにくい設計になっているためである。したがって、RRD のように同じファイルの同じオフセットを部分的に更新し続けるワークロードであっても、物理 NAND セルの実際の書き換え先はコントローラ側で分散される。


リスク評価

bind mount による /var/log, /var/cache, /var/tmp の HDD 退避には、次のようなリスクもある。

  • /etc/fstab に複数の bind mount エントリを書き足すことで、ストレージ依存関係が複雑になる。
  • HDD が何らかの理由でマウントできなかった場合、/var/log などが空ディレクトリのまま起動し、一部サービスが異常状態で動作するリスクがある。
  • バックアップや rsync において bind mount をどこまで含めるかの扱いが複雑化し、誤って二重コピーやループ参照を起こす懸念が出る。
  • トラブルシューティング時に「本来は /var/log だが実体は /mnt/disk1/var/log」という多段の見通しを前提に読む必要が生じる。復旧時の可観測性が下がる。

このように、書き込み先を HDD に逃がすこと自体は技術的には可能であるが、運用 (特に障害時の復旧手順) を複雑化させるというデメリットがある。


最終結論

以上を踏まえ、/var/log、/var/cache、/var/tmp を HDD 側に移し bind mount で差し替えるという案は、最終的に採用しない方針とした。

  • SSD の TBW (70〜150TB 程度) と DWPD をもとにした寿命試算では、1 日 10GB 程度の書き込みであっても 20 年以上というスパンになる。SSD の書き込み寿命は現実的には問題にならない領域である。
  • /var/cache における munin の RRD 更新は、5 分ごとに 8〜32KB 程度のブロックを書き戻すだけであり、1 ホストあたり数十ファイルへの部分上書きが継続したとしても、1 日あたり数百MB 程度に収まる。これは TBW 消費の観点では軽い。
  • bind mount 運用は /etc/fstab の管理や障害復旧を複雑化させる。ブート初期の安定性を確保するには bind mount が有効ではあるものの、複雑さを導入するほどの価値がないと判断した。
  • /home と /opt についてはこれまでどおり HDD 側に逃がしているが、/var は SSD 上に残すほうが全体としての保守性が高い。

結論として、現行構成 (/var は SSD 上で維持する) を継続する。SSD 書き込みを無理に HDD に逃がすのではなく、logrotate や一時ファイルの整理など通常のメンテナンスで十分と判断した。


まとめ

  • /home と /opt は HDD 側に逃がし、シンボリックリンクで参照する構成を継続する。
  • /var/log、/var/cache、/var/tmp の HDD 退避と bind mount は、手順としては用意したが、採用しない。
  • munin の RRD キャッシュは /var/cache 上で継続運用する。RRD は固定長のファイルで、5 分ごとの 8〜32KB 程度の部分上書きにより統計データを維持する。1 ホストあたり数十ファイルが対象で、24 時間あたりの総書き込みは数百MB 程度である。
  • SSD の TBW と DWPD を根拠にすると、これらの書き込みパターンは SSD の寿命を短期で削るほどの負荷ではない。
  • よって、/var の bind mount 移行案は「構成としては可能。しかし保守コストが利益を上回らないため不採用」という結論である。

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)