Snapper

提供: ArchWiki
ナビゲーションに移動 検索に移動

関連記事

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/snapperSNAPPER_CONFIGSconfig が追加されます。

例えば、/ にマウントされたサブボリュームの設定ファイルを作成する場合:

# snapper -c root create-config /

この時点で、設定は有効になっています。cron デーモンが動作している場合、snapper は自動タイムラインスナップショットを作成します。cron デーモンを使っていない場合、systemd サービスとタイマーを使用する必要があります。#有効化/無効化を見てください。

設定について詳しくは snapper-configsman ページを参照。

スナップショットの作成

自動タイムラインスナップショット

Snapper では毎時・毎日・毎月・毎年に保存するスナップショットの数を設定できるスナップショットタイムラインを作成することができます。デフォルトでは1時間毎にスナップショットが取得されます。そして1日1回、タイムラインのクリーンアップアルゴリズムによって"古くなって要らなくなった"スナップショットを削除します。

有効化/無効化

cron デーモンが動作している場合、自動タイムラインスナップショットは自動的に起動します。無効化するには、サブボリュームに存在する設定ファイルを編集して以下を設定してください:

TIMELINE_CREATE="no"

cron デーモンを使っていない場合、パッケージに含まれている systemd ユニットを使うことができます。snapper-timeline.timer起動有効化することで自動タイムラインスナップショットが開始されます。さらに、snapper-cleanup.timer起動有効化すると定期的に古いスナップショットが消去されます。

ノート: cron デーモンと有効化された systemd ユニットがともに動作すると、重複したスナップショットが作成される結果になる場合があります。systemd ユニットを使いつつ cron 側を無効にできるかもしれない一つの手法に、pacmanNoExtract および NoUpgrade を使い、snapper のパッケージの cron ファイルをインストールしない方法があります。[1] を見てください。

スナップショットのリミットの設定

デフォルト設定では、毎時間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
ノート: 設定パラメータ TIMELINE_LIMIT_HOURLY は上記の設定に関連付けられています。上の例では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 スナップショットについては自動タイムラインスナップショットを、prepost については事前事後のスナップショットを見てください。

事前事後のスナップショット

シンプルなスナップショットだけでなく、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 の操作時にスナップショットを自動的に作成するために使用されるパッケージがいくつかあります:

https://github.com/wesbarnett/snap-pac || snap-pac
  • grub-btrfs — (grub-btrfsd) デーモンが含まれており、systemctl を使って有効にすることで新しいスナップショットを探し、それらを自動的に GRUB メニューに含めます。
https://github.com/Antynea/grub-btrfs || grub-btrfs
https://github.com/maximbaz/snap-pac-grub || snap-pac-grubAUR
  • refind-btrfssnap-pac がスナップショットを作成した後に rEFInd にエントリを追加します。
https://github.com/Venom1991/refind-btrfs || refind-btrfsAUR
  • snp — 任意のシェルコマンドの実行前後に snapper でスナップショットを取るラッパー (例:snp pacman -Syu)
https://gist.github.com/erikw/5229436 || snpAUR

読み取り専用スナップショットでの起動

grub-btrfs または snap-pac-grubAUR に依存しているユーザーは、デフォルトでは Snapper のスナップショットは読み取り専用であり、読み取り専用スナップショットを起動する際に固有の困難があることに注意する必要があります。デスクトップマネージャーなどの多くのサービスは書き込み可能な /var ディレクトリを必要とするため、読み取り専用スナップショットから起動すると起動に失敗します。

これを回避するには、スナップショットを書き込み可能にするか、overlayfs を使用してスナップショットを起動する開発者承認の方法を使用して、スナップショットをライブ CD 環境と同様に動作させます。

ノート: ファイルシステムは RAM 内にのみ存在するため、このスナップショット内のファイルに加えた変更は保存されません。

overlayfs を使用してスナップショットをブートするには:

  • grub-btrfs がシステムにインストールされていることを確認してください。
  • /etc/mkinitcpio.confHOOKS 配列の最後に grub-btrfs-overlayfs を追加します: 例えば
    # HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block filesystems fsck grub-btrfs-overlayfs)
  • initramfs を再生成します:
    # mkinitcpio -P

参考文献:

pacman トランザクションで非 Btrfs ブートパーティションをバックアップする

もし /boot パーティションが Btrfs 以外のファイルシステム (ESP など) にある場合、スナップショットによるバックアップはできません。カーネルアップデート時にブートパーティションを自動的に Btrfs root にフックでコピーするには、システムバックアップ#スナップショットと/bootパーティション を参照してください。これは snap-pac とも相性が良いです。

外部ドライブへの増分バックアップ

一部のツールでは、snapper を使用してバックアップを自動化できます。Btrfs#外付けドライブへの増分バックアップ を参照してください。

推奨ファイルシステムレイアウト

ノート: 以下のレイアウトは snapper rollback を使用することは想定していませんが、/ を @ のスナップショットに復元した時の問題を軽減します。フォーラムスレッド を参照してください。

以下は / を簡単に復元できるようにするための推奨ファイルシステムレイアウトです。

ファイルシステムレイアウト
サブボリューム マウントポイント
@ /
@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 に特別な設定をする必要はありません。

ノート:
  • サブボリュームが @ 下に入れ子になっていても、/ のスナップショットには含まれません。/ にマウントしているサブボリュームのスナップショットを保存したい場合は snapper でサブボリュームの設定を行ってください。
  • Btrfs の制限により、スナップショットされたボリュームはスワップファイルを含むことができません。スワップファイルを別のサブボリュームに置くか、スワップパーティションを作成してください。

システムを @ の以前のスナップショットに復元した場合、これらの他のサブボリュームは影響を受けません。たとえば、これにより、サブボリュームが /home にマウントされているため、/home を変更せずに、@ を以前のスナップショットに復元できます。

このレイアウトにより、snapper ユーティリティは / の定期的なスナップショットを取得できると同時に、Arch Live CD が起動できなくなった場合に、Arch Live CD から / を簡単に復元できます。

このシナリオでは、初期セットアップの後、snapper は変更を必要とせず、期待どおりに動作します。

ヒント:
  • @ サブボリュームのスナップショットやロールバックに含めたくないデータを含む他のディレクトリー /var/cache/var/spool/var/tmp/var/lib/machines、(systemd-nspawn), /var/lib/docker。(Docker)、/var/lib/postgres(PostgreSQL)、そして /var/lib/ の下にある他のデータディレクトリです。フラット レイアウトに従うか、ネストしたサブボリュームを作成するかはあなた次第です。一方、/var/lib/pacman の pacman データベースはルートサブボリューム (@) に置かなければなりません。
  • Snapper を @home と他のサブボリュームで実行し、データのスナップショットとロールバック機能を別々に持つことができます。

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 から復元したいスナップショットを確認します:

ヒント: less を使ってファイルを確認できます:
# cat /mnt/@snapshots/*/info.xml | less
次のページを見たいときは space を、終了するときは q を使用します。

<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.logBtrfs.cc(openInfosDir):219 - .snapshots must have owner root というエラーが出力されます)。

孤立したスナップショットによりディスク領域が無駄になる

スナップショットが '失われる' 可能性があり、スナップショットはディスク上にまだ存在しますが、スナッパーによって追跡されません。これにより、大量の無駄なディスク領域が発生する可能性があります。これを確認するには、次の出力を比較します。

# snapper -c <config> list
# btrfs subvolume list -o <parent subvolume>/.snapshots 

最初のリストに存在しない 2 番目のリストのサブボリュームは孤立しており、手動で 削除 することができます。

参照