SDB:BTRFS
目次
既定のサブボリューム
既定では、 openSUSE は btrfs とルートパーティションに対するスナップショットを設定します。スナップショットは、何らかの更新を適用した後で元の状態に戻したり、ファイルをバックアップしたりする目的で使用します。スナップショットは Snapper を利用することで、簡単に管理することができます。
スナップショットをシステムのロールバック (巻き戻し) として使用する場合、ユーザのホームディレクトリや Web サーバ, FTP サーバのコンテンツ、各種のログファイルなどが巻き戻ってしまわないようにするため、配慮が必要です。この配慮はルートファイルシステム内で個別の btrfs サブボリュームを設定することで実現しています。既定では、サブボリュームはスナップショットから除外されるようになっています。 openSUSE では、 YaST を利用してインストールする際、下記のサブボリュームをルートファイルシステムに対して提案します。これらはそれぞれ下記に示す理由によって、スナップショットから除外されます。
/boot/grub2/i386-pc, /boot/grub2/x86_64-efi, /boot/grub2/powerpc-ieee1275, /boot/grub2/s390x-emu
ブートローダ設定のロールバックには対応していないためです。上記のディレクトリはアーキテクチャごとにそれぞれ用意されているもので、はじめの 2 つは AMD64/Intel 64 マシン用、残りの 2 つは IBM POWER, IBM z システム用に用意されるものです。
/home
/home に個別のパーティションを指定しない場合、ロールバックでデータが戻ってしまったりしないようにするため、個別のサブボリュームを設定します。
/opt
サードパーティ製の製品は、通常 /opt 以下にインストールされます。ロールバックでこれらの製品が消えてしまわないようにするため、除外を設定します。
/root
root ユーザのホームディレクトリについても、ロールバックでデータが戻ってしまわないようにしています。
/srv
Web/FTP サーバのデータが含まれています。これらもロールバックでデータが戻ってしまわないようにしています。
/tmp
一時ファイルやキャッシュについても、スナップショットからは除外しています。
/usr/local
このディレクトリは、手作業でソフトウエアをインストールする際に使用するディレクトリです。このディレクトリについても、ロールバックでアンインストールされてしまわないように除外されます。
/var
このディレクトリ以下には様々な目的でファイルが作成されます。ログファイルや一時的なキャッシュのほか、サードパーティ製の製品は /var/opt 内に何かを書き込むことがあります。また、多数の仮想マシンソフトウエアのイメージやデータベースなども、このディレクトリが既定の配置場所になっています。そのため、このディレクトリは様々なデータ損失を防ぐため、スナップショットから除外されるほか、 Copy-On-Write 機能も無効化されます。
古い /var/* サブボリュームの配置 (2018/01以前)
古い SUSE/openSUSE ディストリビューション (SLE 12/Leap 42.x/2018年1月以前の Tumbleweed) では、 /var をルートファイルシステムの一部となるよう btrfs のサブボリュームを構成していました。その代わり、それぞれ下記のディレクトリに対して別途のサブボリュームを作成していました:
/var/opt
サードパーティ製の製品は通常、 /opt 以下にインストールされます。これらの製品に属するアプリケーションの情報は、このディレクトリ内に配置されるのが一般的であるため、このディレクトリを除外しています。
/var/tmp, /var/cache, /var/crash
一時ファイルやキャッシュを含む全てのディレクトリを、スナップショットから除外しています。
/var/lib/libvirt/images
libvirt で管理される仮想マシンのイメージは、既定でこのディレクトリに配置されます。ロールバックの際、仮想マシンのイメージが古いものに戻ってしまわないようにするため、このような除外を設定しています。また、既定ではこのサブボリュームを copy on write 無しで作成します。
/var/lib/mailman, /var/spool
メールファイルやメールキューなどについても、ロールバック時にメールを喪失してしまわないようにするため、除外しています。
/var/lib/named
DNS サーバのゾーンデータが含まれるディレクトリです。ロールバック時にネームサーバがスナップショットから除外されるようにするため、このサブボリュームを作成しています。
/var/lib/mariadb, /var/lib/mysql, /var/lib/pgqsl
これらのディレクトリにはデータベースのデータが含まれます。既定では、これらのサブボリュームは copy on write 無しで作成されます。
/var/log
ログファイルの配置場所です。システムを壊してしまったような場合に、ロールバックでログファイルが元に戻ってしまわないようにするため、このように除外を設定しています。
圧縮型 btrfs ファイルシステム
Leap と Tumbleweed では、 btrfs ファイルシステムの圧縮に対応しています。オプションとして compress または compress-force を指定し、圧縮アルゴリズム (lzo もしくは zlib (既定値)) を選択してください。 zlib 圧縮は圧縮率に優れ、 lzo は処理の高速性と CPU 負荷の少なさに優れています。 例:
mount -o compress /dev/sdx /mnt
ファイルを作成して内容を書き込んだ際、圧縮結果が圧縮前より大きいか同じであった場合、 btrfs はそのファイルに対して恒久的に圧縮を行なわないように設定します。このような動作をしたくない場合は、 compress-force オプションを指定してください。このオプションは、最初に圧縮しにくいデータを書き込むような場合に有効です。
なお、圧縮は新しく作成するファイルに対してのみ実施されます。圧縮せずに書き込まれたファイルは、ファイルシステムを compress や compress-force オプションを指定してマウントし直しても、圧縮されることはありません。これに加えて、 nodatacow 属性が指定されたファイルは、圧縮から除外されます:
chattr +C FILE mount -o nodatacow /dev/sdx /mnt
暗号化は圧縮と全く独立して動作する仕組みです。暗号化と圧縮を指定したパーティションにデータを書き込むと、たとえば下記のようになります:
btrfs filesystem show /mnt btrfs filesystem show /mnt Label: 'Test-Btrfs' uuid: 62f0c378-e93e-4aa1-9532-93c6b780749d Total devices 1 FS bytes used 3.22MiB devid 1 size 2.00GiB used 240.62MiB path /dev/sdb1
このような動作を恒久的に実施したい場合は、 /etc/fstab 設定ファイル内に compress もしくは compress-force オプションを追加してください。たとえば下記のようになります:
UUID=1a2b3c4d /home btrfs subvol=@/home,compress 0 0
空き容量の確認
ファイルシステムの使用率は、通常 df コマンドを利用して確認します。 btrfs ファイルシステムでは、実際のデータ領域に加えてメタデータに対しても領域を割り当てるため、 df の出力が正確には表示できません。
また、 btrfs ファイルシステムでは、まだそれなりに容量が残っているにもかかわらず、容量不足になってしまう場合もあります。これはメタデータ向けの領域がいっぱいになっているために発生する現象で、それぞれ下記のコマンドを実行することで空き容量と使用量を確認することができます:
btrfs filesystem show
sudo btrfs filesystem show / Label: 'ROOT' uuid: 52011c5e-5711-42d8-8c50-718a005ec4b3 Total devices 1 FS bytes used 10.02GiB devid 1 size 20.02GiB used 13.78GiB path /dev/sda3
ファイルシステムの全体サイズとその使用率を表示するコマンドです。最後の行には 2 つの値が示されていますが、この値が一致した時点でファイルシステムが満杯になったことを示します。
btrfs filesystem df
sudo btrfs filesystem df / Data, single: total=13.00GiB, used=9.61GiB System, single: total=32.00MiB, used=16.00KiB Metadata, single: total=768.00MiB, used=421.36MiB GlobalReserve, single: total=144.00MiB, used=0.00B
ファイルシステムに対して、割り当て済みの (total) サイズと使用済みの (used) サイズをそれぞれ表示します。 total と used の値がほぼ等しくなると、メタデータ用の領域が満杯になったことを示します。
btrfs filesystem usage
sudo btrfs filesystem usage / Overall: Device size: 20.02GiB Device allocated: 13.78GiB Device unallocated: 6.24GiB Device missing: 0.00B Used: 10.02GiB Free (estimated): 9.63GiB (min: 9.63GiB) Data ratio: 1.00 Metadata ratio: 1.00 Global reserve: 144.00MiB (used: 0.00B)
Data Metadata System Id Path single single single Unallocated -- --------- -------- --------- -------- ----------- 1 /dev/sda3 13.00GiB 768.00MiB 32.00MiB 6.24GiB -- --------- -------- --------- -------- ----------- Total 13.00GiB 768.00MiB 32.00MiB 6.24GiB Used 9.61GiB 421.36MiB 16.00KiB
上記 2 つのコマンドの出力を両方組み合わせて表示するコマンドです。
詳しくは man 8 btrfs-filesystem および https://btrfs.wiki.kernel.org/index.php/FAQ をお読みください。
snapper を利用することによって disk full が発生する問題について
btrfs ファイルシステムに対して snapper を動作させた際、お使いのシステムのスナップショット内に大量のデータが保存されていることによって、 "No space left on device" (空き容量が不足している) という問題がよく発生します。 snapper を利用することでスナップショットを削除することもできますが、スナップ氏ヨットは即時に削除できるものではありませんし、場合によっては必要な容量を空けられない場合もあります。 snapper を利用してファイルを削除するには:
- 端末 (ターミナルエミュレータ/コンソール) を開きます。
- コマンドプロンプトから "btrfs filesystem show" と入力してコマンドを実行します:
sudo btrfs filesystem show Label: none uuid: 40123456-cb2c-4678-8b3d-d014d1c78c78 Total devices 1 FS bytes used 20.00GB devid 1 size 20.00GB used 20.00GB path /dev/sda3
- 下記のように入力して実行します:
sudo btrfs fi balance start </mountpoint> -dusage=5
上記のコマンドは、空いているチャンクやほぼ空きのチャンクを再配置するコマンドで、メタデータの再生や再配置を行なうためのものです。指定したファイルシステムはそのまま使い続けられますが、処理に際しては長い時間 (1 TB あたり 10 時間以上) を要します。
- snapper でスナップショットの一覧を表示します:
sudo snapper -c root list
- snapper でスナップショットを削除します:
sudo snapper -c root delete (スナップショット番号)
なお、古いスナップショットから順に削除してください。古いスナップショットほど大きなディスク領域を占有しているためです。
壊れた/マウントできない btrfs の修復方法について
下記は btrfs ファイルシステムで重大な問題が発生した場合、特にマウントできなくなってしまった場合などに実施しておくべき手順を説明しています。 dmesg や syslog で記録されるログを読むことで、問題を修復するにあたって飛ばしても良い手順が分かる場合もありますが、 btrfs scrub は非常に安全な修復ツールとして利用できますので、下記の手順の冒頭部については、特に必ず実施しておくことをお勧めします。
- まずは適切な代替システムを起動します。 Rescue システムを起動してもかまいませんし、 openSUSE を別途インストールしてある環境があれば、そこにディスクを接続してもかまいません。また、ライブメディアや openSUSE のインストール DVD 内にあるレスキューシステムでもよいでしょう。なお、インストール DVD にあるレスキューシステムは、同梱されインストールできる openSUSE と同じバージョンのカーネルや btrfs バージョンが利用できますので、こちらをお勧めします。また、 Tumbleweed のディスクには新しいバージョンのカーネルや btrfs が提供されていますので、こちらでもかまいません。
- それぞれのシステムでコンソールを表示し、 root になります。
- まずは /mnt 以下にパーティションをマウントしてみます。これはファイルシステムが本当に壊れているかどうかを確認する手段でもあります:
mount /dev/sda1 /mnt
- マウントできる場合は、大きな破壊は起こっていないものと思われます。下記を実行して修復を実行します:
btrfs scrub start /mnt
下記を実行すると状況を確認することができます:
btrfs scrub status /mnt
- マウントできない場合は、デバイスを直接指定して scrub を実行します:
btrfs scrub start /dev/sda1
同様に、下記を実行すると状況を確認することができます:
btrfs scrub status /dev/sda1
完了したらマウントをお試しください。マウントできれば完了となります。
- scrub を実施したくない場合や、 scrub でも解決しない場合は、 -o usebackuproot を指定してマウントしてみてください:
mount -o usebackuproot /dev/sda1 /mnt
警告!
|
上述の手順は全てが安全な処理であり、ディスクに破壊的な変更を行なわないはずのものです。上記の手順でも問題が解決しない場合は、状況は深刻でバグ報告を実施すべきものである可能性があります。 |
- "btrfs check <デバイス>" を実行します:
btrfs check /dev/sda1
これでも解決しない場合は、表示されたログをどこかに保存して、バグ報告に添付してください。
- "btrfs restore <デバイス> <コピー先ディレクトリ>" を実行して、データを待避させることをご検討ください:
btrfs restore /dev/sda1 /mnt/usbdrive
この処理では問題を解決することはできませんが、ファイルシステム内を検索して、見つかったデータを全て特定のディレクトリに復元することができます。この処理は、たとえばハードウエア障害が発生していて、 btrfs 側の問題ではないような場合に特に有用です。
- "btrfs rescue super-recover <デバイス>" を実行します:
btrfs rescue super-recover /dev/sda1
終わりましたら、再度通常の手順でマウントできないかどうかをご確認ください。マウントできた場合は、これ以降の手順を実施してはなりません。
- さらに "btrfs rescue zero-log <デバイス>" を実行します:
btrfs rescue zero-log /dev/sda1
終わりましたら、再度通常の手順でマウントできないかどうかをご確認ください。マウントできた場合は、これ以降の手順を実施してはなりません。
- さらに "btrfs rescue chunk-recover <デバイス>" を実行します:
btrfs rescue chunk-recover /dev/sda1"
上記の処理は非常に長い時間がかかります。終わりましたら、再度通常の手順でマウントできないかどうかをご確認ください。マウントできた場合は、これ以降の手順を実施してはなりません。
- これまでの手順で実施していなかった場合は、 "btrfs restore <デバイス> <コピー先ディレクトリ>" を実行します:
btrfs restore /dev/sda1 /mnt/usbdrive
- btrfs restore の実行に失敗した場合、ここから先に進むとデータ喪失の可能性が非常に高くなります。あらかじめ btrfs restore でできる限りのデータ救出を実施して進めてください。
警告!
|
上記の手順を実行すると、予期しない変更が加えられてしまう場合が、少しではありますが存在します。また、ここから先の手順は、さらに障害を引き起こしてしまう可能性が高いものです。実行にあたっては、データのほとんど (場合によっては全て) が失われる危険性をご承知おきください。 |
- 最後の手段として、 "btrfs check --repair <デバイス>" を実行します:
btrfs check --repair /dev/sda1