Snapper
関連記事
Snapper は openSUSE の Arvin Schnell によって作られた、Btrfs のサブボリュームと LVM のボリュームのスナップショットの管理を助けるツールです。スナップショットを作成して比較したり、前のスナップショットに戻したり、自動スナップショットが行えます。
目次
インストール
安定版は snapper パッケージからインストールできます。開発版は snapper-gitAUR パッケージで利用可能です。
GUI は snapper-gui-gitAUR パッケージでインストールすることができます。
新しい設定の作成
Btrfs サブボリュームで Snapper の設定を作成する前に、あらかじめサブボリュームが作成されている必要があります。サブボリュームが存在しない場合、Snapper の設定をするまえにサブボリュームを作成してください。
Btrfs サブボリュームが /path/to/subvolume
に存在していて、config
という名前で新しく Snapper の設定を作るには:
# snapper -c config create-config /path/to/subvolume
上記のコマンドを実行すると:
/etc/snapper/config-templates
にあるデフォルトのテンプレートに基づいて/etc/snapper/configs/config
に設定ファイルが作成されます。/path/to/subvolume/.snapshots
にサブボリュームが作成されてスナップショットが保存されます。スナップショットのパスは/path/to/subvolume/.snapshots/#/snapshot
になります (#
はスナップショット番号です)。/etc/conf.d/snapper
のSNAPPER_CONFIGS
にconfig
が追加されます。
例えば、/
にマウントされたサブボリュームの設定ファイルを作成する場合:
# snapper -c root create-config /
この時点で、設定は有効になっています。cron デーモンが動作している場合、snapper は自動タイムラインスナップショットを作成します。cron デーモンを使っていない場合、systemd サービスとタイマーを使用する必要があります。#有効化/無効化を見てください。
設定について詳しくは snapper-configs
の man ページを参照。
スナップショットの作成
自動タイムラインスナップショット
Snapper では毎時・毎日・毎月・毎年に保存するスナップショットの数を設定できるスナップショットタイムラインを作成することができます。デフォルトでは1時間毎にスナップショットが取得されます。そして1日1回、タイムラインのクリーンアップアルゴリズムによって"古くなって要らなくなった"スナップショットを削除します。
有効化/無効化
cron デーモンが動作している場合、自動タイムラインスナップショットは自動的に起動します。無効化するには、サブボリュームに存在する設定ファイルを編集して以下を設定してください:
TIMELINE_CREATE="no"
cron デーモンを使っていない場合、パッケージに含まれている systemd ユニットを使うことができます。snapper-timeline.timer
を起動・有効化することで自動タイムラインスナップショットが開始されます。さらに、snapper-cleanup.timer
を起動・有効化すると定期的に古いスナップショットが消去されます。
スナップショットのリミットの設定
デフォルト設定では、毎時間10個、毎日10個、毎月10個、毎年10個のスナップショットが保存されます。/
など頻繁にサブボリュームに変更を加える場合は、この設定を変更したほうが良いでしょう。#ドライブの負担を抑えるを見て下さい。
以下は、5時間、毎日7個のスナップショットだけを維持して、毎月・毎年は保存しない設定の例です:
/etc/snapper/configs/config
TIMELINE_MIN_AGE="1800" TIMELINE_LIMIT_HOURLY="5" TIMELINE_LIMIT_DAILY="7" TIMELINE_LIMIT_WEEKLY="0" TIMELINE_LIMIT_MONTHLY="0" TIMELINE_LIMIT_YEARLY="0"
スナップショットとクリーンアップの頻度を変更する
systemd タイマーを使っている場合、タイマーを編集してスナップショットの頻度を変更できます。
例えば、snapper-timeline.timer
を編集して以下のようにすることで5分毎にスナップショットが作成されます:
[Timer] OnCalendar= OnCalendar=*:0/5
snapper-cleanup.timer
を編集するときは OnUnitActiveSec
を変更してください。1時間毎に古いスナップショットを消去するには、以下を追加:
[Timer] OnUnitActiveSec=1h
詳しくは Systemd/タイマーや Systemd#ドロップインファイルを参照。
手動スナップショット
シンプルなスナップショット
デフォルトでは Snapper は他のスナップショットと特別な関係を持たない、単純なスナップショットを作成します。
手動でサブボリュームのスナップショットを作成するには、以下のコマンドを実行:
# snapper -c config create --description desc
上記のコマンドはクリーンアップアルゴリズムを使用しないため、スナップショットは明示的に削除するまでずっと残り続けます。
クリーンアップアルゴリズムを設定するには create
の後に -c
フラグを使用して number
, timeline
, pre
, post
のどれかを選択してください。number
は設定ファイルで指定された番号にあわせて定期的にスナップショットを削除します。例えば、number
アルゴリズムを使用するスナップショットを作成するには:
# snapper -c config create -c number
timeline
スナップショットについては自動タイムラインスナップショットを、pre
と post
については事前事後のスナップショットを見てください。
事前事後のスナップショット
シンプルなスナップショットだけでなく、Snapper では事前事後のスナップショットを作成できます。事前 (pre) スナップショットには必ず対応する事後 (post) スナップショットが存在します。このペアによってシステムに変更を加える前後のスナップショットを作成することができます。
事前事後のスナップショットを作成するには、まず事前スナップショットを作成:
# snapper -c config create -t pre -p
上記のコマンドでスナップショット番号が出力されます。
それからシステムに何らかの変更を加えます (例えば新しいプログラムをインストールしたり、ソフトウェアをアップグレードするなど)。
次に事後のスナップショットを作成:
# snapper -c config create -t post --pre-number #
#
は事前スナップショットの番号に置き換えてください。
create
に --command
フラグを指定して、コマンドをラップすることもできます:
# snapper -c config create --command cmd
cmd
は事前事後のスナップショットを作成する間に実行したいコマンドに置き換えてください。
pacman のトランザクションをスナップショットで記録も見てください。
起動時にスナップショットを作成
snapper で root
設定のスナップショットを作成するには snapper-boot.timer
を有効化してください。
スナップショットの確認
作成されたスナップショットを確認するには:
# snapper -c config list
設定の確認
全ての設定を確認するには:
# snapper list-configs
スナップショットの削除
スナップショット番号 #
を削除するには:
# snapper -c config delete #
一度に複数のスナップショットを削除できます。例えば、root 設定の65と70のスナップショットを削除するには:
# snapper -c root delete 65 70
root 以外のユーザーでアクセス
設定は root ユーザーによって作成され、デフォルトでは、root だけが設定を確認したり変更できます。
特定のユーザーからもスナップショットを確認できるようにしたいときは、/etc/snapper/configs/config
ファイルの ALLOW_USERS
の値を変更してください。そうすれば通常ユーザーでも snapper -c configlist
を実行できるようになります。
さらに、ユーザーを使って .snapshots
ディレクトリを閲覧できるようにしたい、それでいてディレクトリの所有者は root のままにしておきたいということが考えられます。そのような場合、使用したいユーザーが属しているグループに、グループ所有者を変更してください。例えば users
を使う場合:
# chmod a+rx .snapshots # chown :users .snapshots
ヒントとテクニック
pacman のトランザクションをスナップショットで記録
pacman の操作時にスナップショットを自動的に作成するために使用されるパッケージがいくつかあります:
- snap-pac — pacman が自動的に snapper を使用して、openSUSE の YaST のような事前/事後のスナップショットを作成します。pacman フック を使用します。
- grub-btrfs — (grub-btrfsd) デーモンが含まれており、systemctl を使って有効にすることで新しいスナップショットを探し、それらを自動的に GRUB メニューに含めます。
- snap-pac-grub — snap-pac がスナップショットを作った後に、grub-btrfs の GRUB エントリを更新します。pacman フック を使用します
- snp — 任意のシェルコマンドの実行前後に snapper でスナップショットを取るラッパー (例:
snp pacman -Syu
)
読み取り専用スナップショットでの起動
grub-btrfs または snap-pac-grubAUR に依存しているユーザーは、デフォルトでは Snapper のスナップショットは読み取り専用であり、読み取り専用スナップショットを起動する際に固有の困難があることに注意する必要があります。デスクトップマネージャーなどの多くのサービスは書き込み可能な /var
ディレクトリを必要とするため、読み取り専用スナップショットから起動すると起動に失敗します。
これを回避するには、スナップショットを書き込み可能にするか、overlayfs を使用してスナップショットを起動する開発者承認の方法を使用して、スナップショットをライブ CD 環境と同様に動作させます。
overlayfs を使用してスナップショットをブートするには:
- grub-btrfs がシステムにインストールされていることを確認してください。
/etc/mkinitcpio.conf
のHOOKS
配列の最後にgrub-btrfs-overlayfs
を追加します: 例えば# HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block filesystems fsck grub-btrfs-overlayfs)
- initramfs を再生成します:
# mkinitcpio -P
参考文献:
- grub-btrfs README (mkinitcpio の代わりに dracut を使用する人のための手順が含まれています)
- Discussion on Github
pacman トランザクションで非 Btrfs ブートパーティションをバックアップする
もし /boot
パーティションが Btrfs 以外のファイルシステム (ESP など) にある場合、スナップショットによるバックアップはできません。カーネルアップデート時にブートパーティションを自動的に Btrfs root にフックでコピーするには、システムバックアップ#スナップショットと/bootパーティション を参照してください。これは snap-pac とも相性が良いです。
外部ドライブへの増分バックアップ
一部のツールでは、snapper を使用してバックアップを自動化できます。Btrfs#外付けドライブへの増分バックアップ を参照してください。
推奨ファイルシステムレイアウト
以下は /
を簡単に復元できるようにするための推奨ファイルシステムレイアウトです。
サブボリューム | マウントポイント |
---|---|
@ | / |
@home | /home |
@snapshots | /.snapshots |
@var_log | /var/log |
subvolid=5 | ├── @ -| | 含まれるディレクトリ: | ├── /usr | ├── /bin | ├── /.snapshots | ├── ... | ├── @home ├── @snapshots ├── @var_log └── @...
/.snapshots
は @snapshots
のマウントポイントです。@...
は /
にマウントするサブボリューム (@
) とは別に保存したいサブボリュームになります。/
のスナップショットを作成するとき、他のサブボリュームはスナップショットに含まれません。ただし、別の snapper 設定を作成することで他のサブボリュームもスナップショットで記録できます。システムを /
のスナップショットの時点まで戻したいと思ったときに、他のサブボリュームには影響が及びません。
例えば、/
をスナップショット時に戻したいが /home
は最新の状態のままにしたい場合、サブボリュームを作成して /home
にマウントしてください。詳しくは Btrfs#サブボリュームをマウントするを参照。
上記のレイアウトは snapper ユーティリティで定期的に /
のスナップショットが作成できるのと同時に、起動できなくなった場合に Arch のライブ CD から /
を簡単に復元することができます。
その場合、初期設定をしたら snapper に特別な設定をする必要はありません。
システムを @
の以前のスナップショットに復元した場合、これらの他のサブボリュームは影響を受けません。たとえば、これにより、サブボリュームが /home
にマウントされているため、/home
を変更せずに、@
を以前のスナップショットに復元できます。
このレイアウトにより、snapper ユーティリティは /
の定期的なスナップショットを取得できると同時に、Arch Live CD が起動できなくなった場合に、Arch Live CD から /
を簡単に復元できます。
このシナリオでは、初期セットアップの後、snapper は変更を必要とせず、期待どおりに動作します。
snapper の設定とマウントポイント
/.snapshots
がマウントされていないこと、フォルダとして存在しないことを確認してください:
# umount /.snapshots # rm -r /.snapshots
それから /
の新しい設定を作成します。
そして @snapshots
を /.snapshots
にマウントしてください。例えば、ファイルシステムが /dev/sda1
に存在する場合:
# mount -o subvol=@snapshots /dev/sda1 /.snapshots
マウントを永続化させるには、fstab にエントリを作成します。
もしくは fstab エントリが既に存在する場合、スナップショットのサブボリュームを再マウントします:
# mount -a
フォルダには 750
のパーミッションを設定してください。
snapper が作成するスナップショットは全て @
サブボリュームの外に保存されるため、snapper のスナップショットを削除しなくても @
を簡単に置き換えることができます。
/
を @
のスナップショットに復元
snapper のスナップショットを使って /
をリストアしたくなったら、まずは Arch Linux のライブ USB/CD を起動します。
トップレベルのサブボリューム (subvolid=5) をマウントしてください。subvolid
マウントフラグは省略します。/dev/sda2 をマウントする例:
# mount -o subvolid=5 /dev/sda2 /mnt
/mnt/@snapshots/*/info.xml
から復元したいスナップショットを確認します:
<description>
タグと <date>
タグを見て、リストアしたいスナップショットが確認できたら、<num>
の番号をメモしてください。
そして @
を他の場所 (例: /@.broken
) にして現在のシステムのコピーを保存します。もしくは btrfs subvolume delete
で @
を削除します。
読み取り専用のスナップショットから読み書き可能なスナップショットを作成:
# btrfs subvol snapshot /mnt/@snapshots/#/snapshot /mnt/@
#
は復元したい snapper のスナップショットの番号に置き換えてください。これで /
は前の状態に戻ります。再起動してください。
スナップショットからのファイルの削除
スナップショット自体を削除せずに、過去のスナップショットから特定のファイルまたはフォルダーを削除したい場合、snappersAUR は、この機能を Snapper に追加するスクリプトです。このスクリプトは、Snapper が現在サポートしていない他のさまざまな方法で過去のスナップショットを操作するために使用することもできます。
追加のスクリプトを使用せずにファイルを削除したい場合は、スナップショットのサブボリュームを読み書き可能にする だけで済みます。次のように実行します:
# btrfs property set /path/to/.snapshots/<snapshot_num>/snapshot ro false
ro=false
であることを確認します:
# btrfs property get /path/to/.snapshots/<snapshot_num>/snapshot ro=false
通常どおり、/path/to/.snapshots/<snapshot_num>/snapshot
内のファイルを変更できるようになりました。シェルループを使用して、スナップショットを一括で処理できます。
スナップショットからファイルを削除
過去のスナップショットから特定のファイルやフォルダを削除したい場合、snapperS というスクリプトが存在します。
スクリプトを使わずにファイルを削除したい場合、以下のコマンドを実行して スナップショットのサブボリュームを読み書き可能 にする必要があります:
# btrfs property set /path/to/.snapshots/<snapshot_num>/snapshot ro false
ro=false
となっていることを確認:
# btrfs property get /path/to/.snapshots/<snapshot_num>/snapshot
ro=false
これで /path/to/.snapshots/<snapshot_num>/snapshot
のファイルは通常通りに編集することが可能になります。
速度低下の防止
頻繁に変更が加わるファイルシステム (例えば多数のシステムアップデートが行われる /
など) で長期間にわたって頻繁にスナップショットを取得すると動作がかなり遅くなることがあります。以下のようにすることで遅くなるのを回避できます:
- スナップショットを作成する価値がない
/var/cache/pacman/pkg
,/var/abs
,/var/tmp
,/srv
などのサブボリュームを作成する。 - 自動タイムラインスナップショットを使う場合に、毎時・毎日・毎周・毎年のスナップショットのデフォルト設定を変更する。
updatedb
デフォルトでは、updatedb
は snapper によって作成された .snapshots
ディレクトリのインデックスも作成してしまい、スナップショットが大量にある場合、深刻な遅延が発生したりメモリが異常に消費される原因になります。以下のように設定ファイルを編集することでインデックスを作成しないように updatedb
を設定できます:
/etc/updatedb.conf
PRUNENAMES = ".snapshots"
quota グループを無効にする
quota グループが原因で大幅な速度低下が発生するという報告があります。たとえば、snapper ls
が結果を返すまでに何分もかかる場合、こちら [2] を参照してください。
quota グループが有効かどうかを確認するには、次のコマンドを使用します:
# btrfs qgroup show /
その後、次のコマンドを使用して quota グループを無効にできます:
# btrfs quota disable /
スナップショットの数を数える
quota グループを無効にしても速度低下が改善されない場合は、スナップショットの数をカウントすると役立つ場合があります。次のように実行します:
# btrfs subvolume list -s / | wc -l
ユーザーデータとログ用のサブボリュームを作成する
ディレクトリに電子メールやログなどのユーザーデータが含まれている場合は、ルートサブボリューム /
ではなく、独自のサブボリュームにディレクトリを保存することをお勧めします。そうすることで、/
のスナップショットが復元された場合、ユーザーデータとログも以前の状態に戻されなくなります。ユーザーデータ用にスナップショットの別のタイムラインを維持できます。/var/log
にログのスナップショットを作成することはお勧めできません。これにより、トラブルシューティングが容易になります。
Snapper#フィルター設定 を使用して、復元中にディレクトリをスキップすることもできます。
こちらも参照して下さい Directories That Are Excluded from Snapshots SLES ドキュメントに記載されています。
トラブルシューティング
Snapper のログ
Snapper は全ての活動を /var/log/snapper.log
に書き出します。何か問題が発生しているように感じたら真っ先にこのファイルをチェックしてください。
毎時・毎日・毎週のスナップショットに問題がある場合、おそらく cronie サービス (もしくはその他の cron デーモン) が動いていなかったのが原因だということが多くあります。
IO エラー
スナップショットを作成しようとすると IO エラーが表示される場合、スナップショットを作成しようとしたサブボリュームと関連付けられている .snapshots ディレクトリもサブボリュームになっていることを確認してください。
また、.snapshots
の所有者が root になっていない可能性もあります (/var/log/snapper.log
に Btrfs.cc(openInfosDir):219 - .snapshots must have owner root
というエラーが出力されます)。
孤立したスナップショットによりディスク領域が無駄になる
スナップショットが '失われる' 可能性があり、スナップショットはディスク上にまだ存在しますが、スナッパーによって追跡されません。これにより、大量の無駄なディスク領域が発生する可能性があります。これを確認するには、次の出力を比較します。
# snapper -c <config> list
# btrfs subvolume list -o <parent subvolume>/.snapshots
最初のリストに存在しない 2 番目のリストのサブボリュームは孤立しており、手動で 削除 することができます。