dumpによるDebianサーバーのバックアップ

さて、LVMに未使用スペースを作りたかったのは、LVMでスナップショットを取りたかったからだ。

近々やらなければならないbusterからbullseyeへのアップグレード。いつもならえいやっと適当にやってしまってトラブってから対処を考えるのだが、今回はMailman 3へのアップグレードという難事業をやった後なので万が一の事態でサーバー再構築となることだけは避けたい。普段から再構築できるようにデータだけは定期的にバックアップを取っているのだが、今回は全ファイルシステムの完全なバックアップを取ってからやることにした。

いろいろとDebianで使えるバックアップツールを調べたのだが、どうにも決定打となるものがない。フルバックアップしてもいちいちファイル単位で戻すことになるのであれば、データだけバックアップしてサーバーを再構築するのと変わらないからだ。どうせフルバックアップするならリストアも機械的に行えばバックアップ時の状態が再現されることが望ましい。となると、古くから使い古されたdumpを使うしか方法がないようだ。dumpでファイルシステム単位でフルバックアップを取れば、Liveシステム等から内蔵ストレージをパーティションしてリストアすれば元の状態に戻すことができるからだ。

とはいえdumpには致命的な弱点がある。それはシステムがオンラインの時にバックアップができないということだ。dumpはもともとテープドライブにバックアップすることを目的としたツールで、ファイルシステムをブロックデバイスとして読み込んでテープのようなブロックデバイスにそのまま書き出すツールだ。なので、処理中にファイルシステムに変更が起きたときに正しくバックアップを行うことができないのだ。だからバックアップするときには必ずシングルユーザーモードにシステムを落としてから行うこととされている。いやいや、バックアップするたびにシステムを落としてオフラインでコンソールで作業とかありえないだろ。 😛

ところが、LVMを使ってパーティション管理をしている場合にはこれを回避する裏技がある。それはスナップショットだ。LVMの利点としてファイルシステムを任意の時点でスナップショットを取ってその状態を固定することができる。スナップショットはリードオンリーのファイルシステムとなるが、一度固定されたスナップショットはオンライン状態でも変更されることはないので、dumpでも安全に書き出すことができるというわけだ。スナップショットは作成時にそれ以降の元になるファイルシステムに生じた変更を記録するワークエリアが必要だ。そのため、LVMに空き領域がないと作ることができないのだ。

というわけで、LVMのスナップショットとdumpを組み合わせたフルバックアップ環境を整えることにした。まあ、dumpそのものはテープ時代以降あまり使われなくなったので、もはやDebianでは標準でインストールされるツールではない。そこでまずはdumpを追加する。

apt install dump

バックアップ時には必ず復元時に元通りのパーティション構成にできるようにパーティション情報を書き出しておこう。それには一連のコマンドの出力を記録しておけばいい。

fdisk -l
pvdisplay
vgdisplay
lvdisplay

バックアップしたいディスクはMBRディスクなので、最初にMBR領域を書き出しておく。このサーバーのメインストレージは/dev/sdbなのでddでその先頭領域をファイルにイメージで書き出す。

dd if=/dev/sdb of=****.img bs=512 count=1

さらにLVMで管理されていない/bootパーティションが/dev/sdb1に存在するので、これをdumpしておく。/bootはカーネル等をアップデートしない限り書き換わることはないので、オンラインでも気にしないでdumpしていい。

dump -0 -f ***.dump /dev/sdb1

残りのLVM上に作られたパーティションはそれぞれスナップショットを作成してからdumpする。便宜上、ボリューム名に_snapをつけた名前でスナップショットを作成する。

lvcreate -s -L 1G -n volume_snap /dev/volue_group/volume

-Lオプションの引数がスナップショットが確保するワークエリアのサイズだ。100%FREEのように指定すると未使用スペースに対する割合で指定できるようだが、今回は別にスナップショット後の変更をそれほど長く保持する必要がないので便宜的に1GBを割り当てている。このスナップショットをdumpする。

dump -0 -f ***.dump /dev/volume_group/volume_snap

最後に必要なくなったスナップショットを削除する。というのもスナップショットを作成したファイルシステムはスナップショットのワークエリアにその後の変更が記録される。そして、このワークエリアを使い切ってしまうと元のファイルシステムがそれ以上書き込むことができなくなってしまうのだ。当然、/varなどはその状態になったらログの書き出しすらできなくなってしまうので、サーバーが正しく動作できなくなってしまう。だから、最後にかならず忘れずにスナップショットを削除しておく。

lvremove -y /dev/volume_group/volue_snap

かならず消していいか確認をしてくるので、-yでyesと自動で答えるようにしているが、間違ってスナップショット元のファイルシステムをふっとばさないように注意が必要だ。

これをバックアップが必要なLVM内のボリュームについて順に行えば完全なバックアップが取れるというわけだ。

とはいえ、bullseyeのアップグレードで問題が起きないことを切に願う。

LVMのボリューム容量再配分

Mailmanを3にアップグレードした結果、思わぬ副作用があった。というのも、Mailman 3はデータをすべて/var/lib/mailmanに置くので、/varの容量が想定外に逼迫してしまったのだ。しかも、今後メーリングリストでメールがやり取りされるたびにメールがアーカイブされて追加で容量を消費していくとなるとこれは早急に/varの容量を増やしておく必要がある。

前回、ルートの容量が不足した時にはリモートから作業する必要があったので容量が有り余っている/homeをアンマウントすることができず、swapを一時的にオフにしてそこから容量を捻出するという荒業を行ったが、今回は手元にサーバーがあるのでコンソールからrootでログインして/homeをアンマウントして捻出しようと思う。

まあ、手順としては前回とほぼ同じなので省略。作業としては、/homeのアンマウント→/homeのext4ファイルシステムのfsck→resize2fsによる/homeのext4ファイルシステムの縮小→lvreduceによる/homeの論理ボリュームの縮小でLVMに未使用スペースを確保する。もともと/homeには40GB弱を割り当てていて、常時使用率が1%なので思い切って20GBまで縮小してしまおう。最後にもう一度/homeをマウントしてデータが破壊されていないことを確認する。

LVMに未使用スペースを確保できたら、今度は/varの拡張だ。ext4ファイルシステムの拡張はマウントしたままでも実行できるので、lvextendで/varの論理ボリュームを拡張したら、続けてresize2fsで/varのext4ファイルシステムを拡張すればいい。もともと4GB弱だった/varを一気に3倍近い10GBまで拡張しておいた。これで当分容量不足を心配する必要はないだろう。

え?なぜ捻出した20GB弱を全部新しくボリュームに割り当てないのかって?それは、この未使用スペースを別の目的に利用する計画があるからさ。その計画はまた後程。