Ubuntu で Btrfs + Snapper:自動スナップショットの設定とシステム障害時の即時ロールバック

Ubuntu tutorial - IT technology blog
Ubuntu tutorial - IT technology blog

Ubuntu システムのバックアップ:データを失ってから後悔しないために

これまで 20 台以上の VPS に Ubuntu Server 22.04 をインストールしてきたが、必ず最初にやることが一つある——他の何かをインストールする前に、自動スナップショットを設定することだ。理由は単純で、一度 apt upgrade がカーネルに干渉して、レスキューモードから手動復旧するのに 3 時間近くかかったことがある。それ以来、Btrfs スナップショットはサーバーセットアップのチェックリストの最初の項目になった。

Ubuntu で一般的なバックアップ手法の比較

Btrfs + Snapper に決める前に、3 つの方法を試した。どれも紙の上では問題なく見えたが、実際にサーバーで使ってみると欠点が見えてきた。

1. rsync — 従来のファイルバックアップ

rsync は使い慣れていてスクリプト化も簡単、特別なセットアップも不要だ。しかし、最も重要な部分で問題がある:

  • 本当のスナップショットではない——特定の時点でのシステム状態を正確にキャプチャできない
  • 復旧が遅い:全ファイルをコピーし直す必要があり、時間がかかる
  • カーネルが壊れたり grub にエラーが発生した場合、ブートローダーをロールバックできない
  • バックアップのサイズがパーティションサイズに比例して増加し、容量効率が悪い

2. Timeshift — 使いやすいが柔軟性に欠ける

一見すると Timeshift の方が優れているように見える:使いやすい GUI、rsync モードと Btrfs モードの両方をサポート。しかしサーバーで実際に使うと:

  • rsync モードは通常の rsync と同様に遅くストレージを消費する
  • Btrfs モードは / と /home のスナップショットのみで、カスタマイズの余地が少ない
  • apt との自動連携がない——アップデート前に手動でスナップショットを作成する必要がある
  • クリーンアップポリシーがシンプルすぎて、Snapper ほど柔軟ではない

3. Btrfs + Snapper — ファイルシステムレベルのスナップショット

この方法はすべての重要なサーバーで使っている。スナップショットはファイル単位ではなく、ファイルシステムレベルで動作する。パーティションが何 GB あっても 1 秒未満で完了する。変更された部分だけを保存し、全体を複製しない。そして、システムが起動できない場合でも GRUB ブートメニューから直接ロールバックできる。

Btrfs + Snapper のメリットとデメリット分析

実際のメリット

  • スナップショット作成がほぼ瞬時:Copy-on-write ファイルシステム——スナップショット作成にデータコピーが不要
  • ストレージ節約:スナップショットは直前の状態からの差分のみを保存し、全体を複製しない
  • GRUB からのロールバック:システムが起動できない場合でも、ブートメニューから古いスナップショットを選択できる
  • 完全な自動化:時間・日・週単位のタイムラインスナップショット、古いスナップショットを自動削除するクリーンアップポリシー
  • apt フックとの連携:apt install/upgrade の前後に自動スナップショット——何も覚えておく必要がない

導入前に知っておくべきデメリット

  • Ubuntu インストール時にパーティションを Btrfs でフォーマットする必要がある——ext4 からの変換は容易ではない
  • Btrfs のサブボリュームの概念を理解する必要がある(難しくはないが、事前に読んでおく必要がある)
  • スナップショットはシステムと同じディスクに保存される——ディスクが物理的に壊れた場合は本当のバックアップにはならない
  • 稼働中のデータベース(MySQL、PostgreSQL)は別途バックアップが必要——ファイルシステムスナップショットは一貫性を保証しない

どの方法が適しているか?

ケースごとに簡単にまとめると:

  • 本番サーバーで、アップデート失敗時に素早くロールバックしたい → Btrfs + Snapper(この記事)
  • デスクトップ Ubuntu で /home の簡単なバックアップが必要 → Timeshift rsync モードの方が簡単
  • 別のサーバーやクラウドにデータをバックアップしたい → rsync、restic、または borgbackup

ここからは Ubuntu Server 向けの Btrfs + Snapper に絞って説明する。

ステップバイステップの導入手順

前提条件:Ubuntu を Btrfs でインストール

Ubuntu 22.04 のインストール時、ディスク選択の手順で Custom Storage Layout を選択し、root パーティションを Btrfs でフォーマットする。Ubuntu インストーラーが自動的に root 用のサブボリューム @ と /home 用の @home を作成する。

現在のシステムが既に Btrfs を使用しているか確認:

df -T /
# Type 列が btrfs であること

sudo btrfs subvolume list /
# サブボリューム @ と @home が表示されること

ステップ 1:Snapper と snapper-support をインストール

sudo apt update
sudo apt install -y snapper snapper-support

snapper-support は grub-btrfs を依存関係として取り込み、GRUB ブートメニューにスナップショット一覧を自動的に追加する。

ステップ 2:root 用の Snapper 設定を作成

sudo snapper -c root create-config /

# 作成した設定を確認
sudo snapper -c root get-config

ステップ 3:スナップショット保持ポリシーを調整

デフォルトの Snapper は保持数が多すぎる——チューニングしないと思っているより早くストレージが増加する。通常は次のように変更している:

sudo nano /etc/snapper/configs/root

以下の行を見つけて修正する:

# 手動スナップショットの最大保持数
NUMBER_LIMIT="5"

# タイムラインによる自動スナップショット作成と削除を有効化
TIMELINE_CREATE="yes"
TIMELINE_CLEANUP="yes"

# 各時間軸で保持するスナップショット数
TIMELINE_LIMIT_HOURLY="3"
TIMELINE_LIMIT_DAILY="5"
TIMELINE_LIMIT_WEEKLY="2"
TIMELINE_LIMIT_MONTHLY="1"
TIMELINE_LIMIT_YEARLY="0"

ステップ 4:Snapper のタイマーを有効化

sudo systemctl enable --now snapper-timeline.timer
sudo systemctl enable --now snapper-cleanup.timer

# タイマーが動作しているか確認
sudo systemctl status snapper-timeline.timer

ステップ 5:apt 実行前に自動スナップショットを取るため apt-btrfs-snapper をインストール

このセットアップで一番気に入っている部分だ。apt install や apt upgrade を実行するたびに、システムが自動的に前後のスナップショットを作成する——何も覚えておく必要がない:

sudo apt install -y apt-btrfs-snapper

# すぐにテスト:パッケージをインストールして自動スナップショットを確認
sudo apt install -y htop
sudo snapper -c root list
# 先ほどの apt 実行の "pre" と "post" の 2 つの新しいスナップショットが表示される

ステップ 6:GRUB を更新してブートメニューにスナップショットを追加

sudo update-grub

# grub-btrfs がエントリを生成済みか確認
grep -i btrfs /boot/grub/grub.cfg | head -5

これ以降、起動時に GRUB に 「Ubuntu Snapshots」 サブメニューが表示され、起動するスナップショットを選択できるようになる。

障害発生時のロールバック方法

システムが正常に動作している場合のロールバック

# 現在のスナップショット一覧を表示
sudo snapper -c root list
# ID | Type    | Date                      | Description
# 0  | single  | 2026-10-08 10:00:00 +0900 | current
# 1  | pre     | 2026-10-08 11:00:00 +0900 | apt: apt-get upgrade
# 2  | post    | 2026-10-08 11:05:00 +0900 | apt: apt-get upgrade

# スナップショット 1 と現在の状態の差分ファイルを確認
sudo snapper -c root diff 1..0

# スナップショット番号 1 の状態にロールバック(それ以降のすべての変更を元に戻す)
sudo snapper -c root undochange 1..0

システムが起動できない場合のロールバック

  1. マシンを再起動し、GRUB メニューに入る(Shift または Esc を長押し)
  2. Ubuntu Snapshots を選択 → ロールバックしたいスナップショットを選択
  3. システムがそのスナップショットで起動する(確認のための読み取り専用モード)
  4. 起動できたら、実際にロールバックして再起動するコマンドを実行:
# スナップショット ID 5 にロールバック(一覧の ID 番号に合わせて変更すること)
sudo snapper -c root rollback 5

sudo reboot

手動でのスナップショット管理

# 重要な作業の前に手動でスナップショットを作成
sudo snapper -c root create --description "docker-install-before"

# Btrfs が使用している合計容量を確認
sudo btrfs filesystem usage /

# 不要な手動スナップショットを削除
sudo snapper -c root delete 3

# 複数のスナップショットをまとめて削除
sudo snapper -c root delete 3 4 5

長期使用から得た実践的な注意点

  • スナップショット ≠ 完全なバックアップ:スナップショットはシステムと同じディスクに保存される——ディスクが物理的に壊れればスナップショットも失われる。重要なデータ(データベース、アップロードファイル)は rsync や restic で外部にバックアップする必要がある。
  • 定期的な容量確認:月に一度 btrfs filesystem usage / を実行すること。CoW スナップショットは時間とともに蓄積される——クリーンアップタイマーが自動で削除するが、追加で確認しても損はない。
  • /home を別途スナップショット:/home もスナップショットしたい場合は、別途設定を作成する:sudo snapper -c home create-config /home、その後同様にポリシーを調整する。
  • データベースの一貫性:稼働中の MySQL や PostgreSQL はファイルシステムスナップショット時に一貫性が保証されない。本番データベースには mysqldump や pg_dump を使った別途の cron ジョブを併用すること。

このセットアップには約 15 分かかるが、何度も助けられてきた——特に apt full-upgrade がカーネルや重要なシステムライブラリに干渉した際に。ロールバック後、2 分以内にサーバーがクリーンな状態に戻り、レスキューモードで調査したり再インストールしたりする必要がない。

Share: