TT Lab
はじめる
学ぶ 学習パス コース

ストレージ実務 — RAID・スナップショット・iSCSI・fio

戻る道を先に作る — LVM スナップショット・ファイルシステム選択・シンプロビジョニング

TT Labで続きを見る

一言でいうと

変更の直前に取ったLVMスナップショットは、「元に戻せる」を数秒で作ります。その代わり、スナップショットは容量がいっぱいになると役に立たなくなり、バックアップではなく、元と同じディスクにあります。ファイルシステムは、最初に選ぶときに縮小できるかも一緒に見る必要があり、シンプロビジョニングは、存在しない容量を約束することなので、監視がついてきます。

なぜ必要なのか

パッケージのアップグレード、設定ファイルの大量修正、スキーマ変更のような作業は、「失敗したら元に戻す」を前提に承認されます。ところが、元に戻す方法が「バックアップから復元」しかなければ、1時間かかり、その間に新しく入ってきたデータは失います。作業の直前にボリュームの姿を瞬間的に固定しておき、失敗したらその瞬間に戻る手段が必要でした。それがスナップショットです。

もう1つあります。ボリュームを余裕をもって確保したあと、別のボリュームに容量が必要になることはよくあります。そのとき「縮小できないファイルシステム」を選んでいたなら、選択肢は、新しく作って移すことだけです。ファイルシステムの選択は、最初の一度で決まり、長く影響します。

どう動くのか

COWスナップショット。lvcreate(8)の-sは、元のLVのスナップショットを作ります。作る瞬間には、何もコピーしません。その後、元のどのブロックかが初めて変更されるときに、古い内容をスナップショットの領域に移しておくcopy-on-write方式です。そのため、スナップショットのサイズ(-L)は、元のサイズではなく、「スナップショットを置いている間に変わる量」に合わせます。lvsのData%列が、その領域をどれだけ使ったかを見せますが、100%に達すると、スナップショットは無効になって捨てられます。大きな作業の途中でスナップショットが静かに無効になると、元に戻す道がなくなったことにも気づかず、作業を続けてしまいます。

元に戻す操作はマージです。lvconvert(8)の--mergeは、スナップショットの内容を元に書き戻して、スナップショットをなくします。元が開かれている(マウントされている)と、マージは次のアクティブ化まで延期されるので、作業計画書には「アンマウント → マージ → 再マウント」の順で書きます。マージが終わると、スナップショットLVは一覧から消えます。

スナップショットはバックアップではありません。元と同じVG、たいていは同じディスクにあります。ディスクが死ぬと、元とスナップショットが一緒に消えます。そして、COWスナップショットが付いている間は、元への最初の書き込みのたびにコピーがもう1回起きて、書き込みが遅くなります。そのため、スナップショットは作業ウィンドウの間だけ置いて、終わったら消します。

ファイルシステムを選ぶときの着眼点。どちらもジャーナリングファイルシステムで、どちらもマウントしたまま拡張できます。違いは、縮小するときに出ます。

ext4 XFS
オンライン拡張 resize2fs xfs_growfs(マウント状態でのみ)
縮小 アンマウント後にresize2fsで可能 サポート範囲外として設計する。作り直して移す
よくある既定値 DebianとUbuntu RHEL系

resize2fs(8)は、マウントされたext4を大きくでき、縮小はアンマウントした状態でのみ行います。xfs_growfs(8)は、名前のとおり、大きくするツールです。最近のxfsprogsに、最後のアロケーショングループの空き領域だけを縮小する実験的な機能が入りましたが、運用の設計では、「XFSは縮小できない」を前提に置きます。

縮小するときは、順序が命です。まずファイルシステムを目標より小さく縮小し、次にLVを縮小し、最後にファイルシステムをLVのサイズに合わせ直します。LVを先に縮小すると、ファイルシステムの末尾が切り捨てられます。lvreduce -rは、この過程をfsadmに任せて一度に行いますが、何が起きているかを知ったうえで使う必要があります。

シンプロビジョニング。lvmthin(7)のシンプールは、実際の容量を持つプールで、シンボリュームは、そのプールから書き込むときに容量を受け取ります。そのため、400MiBのプールの上に、1GiBのシンボリュームを作れます。これがオーバープロビジョニング(overprovisioning)です。複数のボリュームがすべていっぱいになるわけではないという統計に頼るもので、仮想化のメモリオーバーコミットと同じ取引です。lvmthin(7)は、プールがいっぱいになると書き込みが止まったりエラーになったりすると警告し、プールの使用率を監視して自動的に拡張する設定(thin_pool_autoextend_threshold)を説明しています。プールを拡張するためのVGの余裕がなければ、その設定も役に立ちません。

現場での姿

変更作業計画書の「事前作業」欄に、スナップショットが入るチームが多いです。良い計画書は、スナップショットのサイズの根拠(作業が変更する量の見積もり)と、「スナップショットの使用率が何%を超えたら中止」という基準まで書きます。作業が終わったらスナップショットを消す行も書きます。消し忘れたスナップショットが、数週間後に100%になって無効になったり、書き込み性能を削り続けていたりする場合がよくあります。

「このボリュームを半分に縮小して、隣のボリュームに回そう」という依頼が、XFSの前で止まることもよく見ます。RHEL系の既定値がXFSなので、インストールのときに何も考えずに選んでしまうからです。縮小する可能性があるボリュームなら、最初からext4にするか、余裕をもって確保せずに小さく始めて拡張する方向で設計します。

次のラボですること

3GiBのループデバイスでVGのvg_stoを立ち上げ、XFSボリュームのlv_appに、設定ファイルと注文ファイルを置きます。スナップショットを取ったあと、わざと間違った変更をして、スナップショットの使用率を記録し、マージで元に戻します。続いて、XFSをオンラインで拡張し、ext4ボリュームを作って、データを守りながらオフラインで縮小します。最後に、400MiBのシンプールの上に1GiBのシンボリュームを作り、オーバープロビジョニングを目で確かめます。