FedoraでBtrfsスナップショットを使う:システムのバックアップとロールバックを素早く実現する方法

Fedora tutorial - IT technology blog
Fedora tutorial - IT technology blog

5分ですぐ実践 — 複雑なセットアップ不要

Fedora 33以降を使っているなら、ルートファイルシステムはデフォルトでBtrfsになっています。つまり、今すぐ何も追加インストールせずにスナップショットを作成できます。

Btrfsを使っているか素早く確認:

df -T /
# Type列に「btrfs」と表示されていればOK

ルートサブボリュームのread-onlyスナップショットを作成:

# スナップショット用ディレクトリを作成(一度だけ実行)
sudo mkdir -p /.snapshots

# 日時付きのスナップショットを作成
sudo btrfs subvolume snapshot -r / /.snapshots/root-$(date +%Y%m%d-%H%M)

作成したスナップショットを確認:

sudo btrfs subvolume list / | grep snapshots

完了です — システム全体の状態のバックアップが取れました。後でファイルを復元したい場合は、このスナップショットをマウントしてコピーするだけです。

なぜスナップショットが必要か — 実体験から

Fedoraをメインの開発マシンとして2年間使ってきて、パッケージの更新速度にはかなり満足しています。ただ、その更新の速さゆえに、アップグレード後に正常に動いていたものが壊れることが時々あります。特に多いのはNVIDIAドライバや、ABIが変わったPythonライブラリの問題です。

スナップショットを知る前は、問題が発生するたびに何時間もデバッグしていました。今はずっと楽になりました:dnf upgradeの前にスナップショットを作っておき、何か壊れたら数分でロールバック、何も失いません。

スナップショットはどう機能するか?

Btrfsスナップショットはデータを丸ごとコピーするわけではありません。Copy-on-Write(CoW)という仕組みを使っています。スナップショット作成時、Btrfsは既存のデータブロックへの参照を記録するだけで現在の状態を保持します。その後ファイルを変更した時に初めて、Btrfsは古いブロックを新しい場所にコピーしてから新しいデータを書き込みます。

この仕組みのおかげで、スナップショットの作成は1秒未満で完了し、作成直後はほぼディスク容量を消費しません。容量はその後のシステムの変更量に応じて徐々に増えていきます。

従来のバックアップとの比較

  • 作成速度:Btrfsスナップショットは1秒未満で完了。rsyncによるバックアップは数十分かかります。
  • 初期容量:作成直後のスナップショットはほぼ0バイト。コピーバックアップは即座にデータ量が2倍になります。
  • 制限:スナップショットは同一のBtrfsファイルシステム内でしか機能しません。外付けドライブへのバックアップには別途ツールが必要です。

Snapperで自動化する — 一度設定すればあとは自動

手動でのスナップショット作成は最初の試みには十分ですが、実際には危険な操作をする前に忘れてしまいます。Snapperがその問題を解決してくれます — スナップショットを管理するだけでなく、最も重要な機能として、DNFと連携して毎回のアップデートの前後に自動的にシステム状態を記録します。

SnapperとDNFプラグインのインストール

sudo dnf install snapper python3-dnf-plugin-snapper

ルートサブボリューム用のSnapper設定を作成:

sudo snapper -c root create-config /

作成されたデフォルト設定を確認:

sudo snapper -c root get-config

Snapperで手動スナップショットを作成

# 説明付きでスナップショットを作成
sudo snapper -c root create --description "Nginx設定を試す前"

# スナップショット一覧を表示
sudo snapper -c root list

出力はこのようになります:

  # | Type   | Pre # | Date                      | User | Description
----+--------+-------+---------------------------+------+-------------------------
  0 | single |       |                           | root | current
  1 | single |       | 2025-03-15 09:30:12 +0900 | root | Nginx設定を試す前

dnf実行時の自動スナップショット

python3-dnf-plugin-snapperをインストールすると、dnfを実行するたびに「pre」と「post」のスナップショットペアが自動的に作成されます。追加の操作は不要です:

sudo dnf upgrade
# Snapperがアップグレード開始前に「pre」スナップショットを自動作成
# アップグレード完了後に「post」スナップショットを自動作成

アップグレード完了後に結果を確認:

sudo snapper -c root list
# type「pre」と「post」のスナップショットペアが表示されます

2つのスナップショット間の差分を比較

最もよく使う機能は、アップグレード後にどのファイルが変更されたかを確認することです。特にどの設定が上書きされたかを調べるのに非常に役立ちます:

# スナップショット3(pre)と4(post)を比較
sudo snapper -c root status 3..4

# 特定ファイルの詳細な差分を確認
sudo snapper -c root diff 3..4 /etc/nginx/nginx.conf

システム障害時のロールバック

特定ファイルのロールバック — 軽微なトラブルに最速

誤ってファイルを削除したり、編集後に設定が壊れてしまった場合:

# スナップショット1から現在の状態(0)へ特定ファイルを復元
sudo snapper -c root undochange 1..0 /etc/fstab

# またはスナップショットを手動マウントしてファイルをコピー
sudo mount -o ro,subvol=/.snapshots/1/snapshot /dev/sda3 /mnt
cp /mnt/etc/fstab /etc/fstab
sudo umount /mnt

GRUBからシステム全体をロールバック

より深刻な場合 — 新しいカーネルが起動しない、またはアップグレードでデスクトップ環境が壊れた場合。grub-btrfsを追加インストールして、GRUBにスナップショットのブートメニューを表示させます:

sudo dnf install grub-btrfs
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

再起動すると、GRUBに「Fedora snapshots」という項目が追加され、古いスナップショットから起動できます。保持したいスナップショットへの起動に成功したら:

sudo snapper rollback
sudo reboot

注意snapper rollbackはSnapperの標準レイアウトのサブボリュームで適切に機能します。Fedoraのデフォルトレイアウト(サブボリューム@@home)の場合、本番環境で使用する前にSnapperのドキュメントで互換性を確認することをお勧めします。

スナップショットを長く使いこなすための実践的なTips

スナップショット前の習慣のためのエイリアスを作成

~/.bashrcに追加して、危険な操作の前にすばやくスナップショットを作成できるようにします:

# ~/.bashrcに追加
alias snap-now='sudo snapper -c root create --description "Manual: $(date +%Y%m%d-%H%M)"'

# bashrcを再読み込み
source ~/.bashrc

# 使い方: snap-now && sudo dnf upgrade

容量管理 — スナップショットでディスクを埋めないように

数週間の定期的なアップデートを経ると、/.snapshotsはシステムの変更量に応じて5〜20GBを消費する可能性があります。タイムラインに従って自動クリーンアップするようSnapperを設定し、スナップショット数を適切に維持しましょう:

sudo snapper -c root set-config \
  TIMELINE_CREATE=yes \
  TIMELINE_LIMIT_HOURLY=5 \
  TIMELINE_LIMIT_DAILY=7 \
  TIMELINE_LIMIT_WEEKLY=2 \
  TIMELINE_LIMIT_MONTHLY=1 \
  TIMELINE_LIMIT_YEARLY=0

不要な古いスナップショットを削除:

# スナップショット5を削除
sudo snapper -c root delete 5

# 複数のスナップショットを一括削除
sudo snapper -c root delete 3-8

# スナップショットの使用容量を確認
sudo btrfs filesystem du -s /.snapshots/*

btrfs sendで外付けドライブにスナップショットをバックアップ

同じドライブ上のスナップショットはソフトウェアの障害からは守れますが、ハードウェアの故障には対応できません。本当のバックアップのためには、btrfs sendを使ってスナップショットを外付けドライブに送信します:

# 外付けドライブが/backupにマウントされていると仮定(Btrfsファイルシステムが必要)
# 完全なスナップショットを送信
sudo btrfs send /.snapshots/1/snapshot | sudo btrfs receive /backup/

# 増分送信 — 前のスナップショットからの変更分のみ送信、非常に高速
sudo btrfs send -p /.snapshots/1/snapshot /.snapshots/2/snapshot | \
  sudo btrfs receive /backup/

増分バックアップは2つのスナップショット間で変更されたデータのみを送信します。数十GBをコピーする代わりに、毎日のバックアップで数百MBを転送するだけです。

このワークフローを使い始めてから、dnf upgradeの前に不安を感じることはほとんどなくなりました。スナップショットの作成は1秒未満、ロールバックは数分で完了 — 問題が発生した時の何時間もかかるデバッグと比べれば、まったく割に合うトレードオフです。

Share: