Posted at

LVM シンプロビジョニングボリューム

More than 3 years have passed since last update.

LVM のシンプロビジョニングボリュームを使ってみました。

VirtualBox に CentOS 7 をインストールした後に 5G のディスクを追加して試しています。


追加ディスクで PV を作成します(いきなり vgcreate しても大丈夫なようです)

pvcreate /dev/sdb

ボリュームグループを作成します。-s は物理エクステントのサイズを指定しているのですが詳細は割愛します。

vgcreate -s 32MB vg0 /dev/sdb

ボリュームグループにシンプールを作成します。

lvcreate--thin を付け、VolumeGroupName/ThinPoolName の形式でプール名を指定します。-L 512M はシンプールに割り当てるサイズです。

lvcreate --thin -L 512M vg0/thin

次のように作成しても同じです。

lvcreate --thinpool thin -L 512M vg0

作成したシンプールにシンプロビジョニングされたボリュームを作成します。

lvcreate--thin を付け、-V 10G でボリュームのサイズ、-n vol でボリュームの名前、vg0/thin は↑で作成したシンプールの名前です。

lvcreate --thin -V 10G -n vol vg0/thin

シンプールには 512MB しか割り当てていませんが、シンプロビジョニングなので 10GB のボリュームでも作成できます。

ボリュームにファイルシステムを作成してマウントしてサイズを確認します。

mkfs.xfs /dev/vg0/vol

mount -t xfs /dev/vg0/vol /mnt
df -h /mnt/

10G となっています。

Filesystem           Size  Used Avail Use% Mounted on

/dev/mapper/vg0-vol 10G 33M 10G 1% /mnt

256MB ほど書き込みます。

dd if=/dev/zero of=/mnt/data bs=256M count=1

シンプールは 50% 程度消費されていることがわかります。

lvs

LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert
thin vg0 twi-a-tz-- 512.00m 52.17
vol vg0 Vwi-aotz-- 10.00g thin 2.61

さらに 512 MB 書き込んでみます。

dd if=/dev/zero of=/mnt/data2 bs=512M count=1

応答がなくなりました・・・

lvs で見てみるとシンプールを 100% 使いきっています。

lvs

LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert
thin vg0 twi-a-tz-- 512.00m 100.00
vol vg0 Vwi-aotz-- 10.00g thin 5.00

シンプールのサイズを増やします。

lvresize -L 1G /dev/vg0/thin

dd はエラーで終わりました。

dd if=/dev/zero of=/mnt/data2 bs=512M count=1

dd: error writing ‘/mnt/data2’: Input/output error
1+0 records in
0+0 records out
480530432 bytes (481 MB) copied, 47.777 s, 10.1 MB/s

/mnt は I/O エラーになります。

ls /mnt

ls: cannot access /mnt: Input/output error

マウントしなおすとアクセスできるようになりました。

umount /mnt

mount -t xfs /dev/vg0/vol /mnt
ll /mnt

ボリュームの削除は普通の論理ボリュームと同じです。

umount /mnt

lvremove /dev/vg0/vol


シンプロビジョニングスナップショット

シンプロビジョニングされたボリュームからは、シンプロビジョニングされたスナップショットを作成することができます。

(シンプロビジョニングではない)通常のスナップショットボリュームのようにあらかじめサイズを決める必要がありません。

先ほどと同じようにシンプロビジョニングされたボリュームを作成します。

lvcreate --thin -V 1G -n vol1 vg0/thin

ファイルシステムを作成&マウントして適当に書き込みます。

mkfs.xfs /dev/vg0/vol1

mount -t xfs /dev/vg0/vol1 /mnt
touch /mnt/test1
umount /mnt

シンプロビジョニングされたスナップショットを作成します。

普通のスナップショットなら -L 1G のようにサイズを指定するところですが、シンプロビジョニングされたスナップショットではサイズは指定しません。

lvcreate -s -n vol2 vg0/vol1

lvs で見てみると次のように表示されます。Origin の箇所をみれば vol2 が vol1 のスナップショットであることがわかります。

lvs

LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert
thin vg0 twi-a-tz-- 1.00g 1.04
vol1 vg0 Vwi-a-tz-- 1.00g thin 1.04
vol2 vg0 Vwi---tz-k 1.00g thin vol1

元ボリューム(vol1)に追加で書き込みます。

mount -t xfs /dev/vg0/vol1 /mnt

touch /mnt/test2
umount /mnt

vol1 をスナップショットに戻してみます。

lvconvert--merge を付け、/dev/vg0/vol2 のようにスナップショットを指定すると、そのスナップショットが元ボリュームに書き戻されます。

lvconvert --merge /dev/vg0/vol2

マウントして内容を確認すると、スナップショットの時点に戻っていることがわかります。

mount -t xfs /dev/vg0/vol1 /mnt

ls /mnt/
test1

umount /mnt/


元ボリュームを削除

↑の手順ではスナップショットから元ボリュームに復元しましたが、元ボリュームを削除すればスナップショットが通常のボリュームに変わります。

先ほどの手順と同じようにスナップショットを作成します。

lvcreate -s -n vol2 vg0/vol1

元ボリュームをマウントして適当に書き込みます。

mount -t xfs /dev/vg0/vol1 /mnt

touch /mnt/test2
umount /mnt

元ボリュームを削除します。

lvremove /dev/vg0/vol1

vol2 をアクティブ化します。これをやっておかないと vol2 が /dev/vg0/ に現れずマウントできません。

lvchange -kn -ay vg0/vol2

vol2 をマウントして内容を確認すると、スナップショットを作成した時点の内容になっていることがわかります。

mount -t xfs /dev/vg0/vol2 /mnt

ls /mnt
test1

umount /mnt


スナップショットに書き込む

通常の LVM スナップショットと同じように、スナップショットをマウントして書き込むこともできます。

vol2 からスナップショットを作成します。

lvcreate -s -n vol3 vg0/vol2

vol3 をアクティブ化します。

lvchange -kn -ay vg0/vol3

vol3 をマウントして書き込みます。

mount -t xfs /dev/vg0/vol3 /mnt

touch /mnt/test3
umount /mnt

さらに、vol3 からスナップショットを作成してアクティブ化します。

lvcreate -s -n vol4 vg0/vol3

lvchange -kn -ay vg0/vol4

vol4 をマウントして書き込みます。

mount -t xfs /dev/vg0/vol4 /mnt

touch /mnt/test4
umount /mnt

次のように階層的なスナップショットになっています。

lvs

LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert
thin vg0 twi-a-tz-- 1.00g 1.46
vol2 vg0 Vwi-a-tz-- 1.00g thin 1.04
vol3 vg0 Vwi-a-tz-- 1.00g thin vol2 1.04
vol4 vg0 Vwi-a-tz-- 1.00g thin vol3 1.04

それぞれのボリュームをマウントして内容を確認してみます。

mount -t xfs /dev/vg0/vol2 /mnt

ls /mnt
test1

umount /mnt
mount -t xfs /dev/vg0/vol3 /mnt

ls /mnt
test1 test3

umount /mnt
mount -t xfs /dev/vg0/vol4 /mnt

ls /mnt
test1 test3 test4

umount /mnt

ここで階層の中間である vol3 を削除すると。

lvremove /dev/vg0/vol3

vol4 の親が vol2 になるかと思ったのですが、vol4 は独立したボリュームになりました。

lvs

LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert
thin vg0 twi-a-tz-- 1.00g 1.25
vol2 vg0 Vwi-a-tz-- 1.00g thin 1.04
vol4 vg0 Vwi-a-tz-- 1.00g thin 1.04


ボリュームから複数回スナップショットを作成

1つのボリュームに 100MB ずつファイルを書き込みつつ複数回スナップショットを作成してみます。

lvcreate --thin -V 1G -n vol1 vg0/thin

mkfs.xfs /dev/vg0/vol1

mount -t xfs /dev/vg0/vol1 /mnt
dd if=/dev/zero of=/mnt/data1 bs=100M count=1
umount /mnt

lvcreate -s -n vol2 vg0/vol1

mount -t xfs /dev/vg0/vol1 /mnt
dd if=/dev/zero of=/mnt/data2 bs=100M count=1
umount /mnt

lvcreate -s -n vol3 vg0/vol1

mount -t xfs /dev/vg0/vol1 /mnt
dd if=/dev/zero of=/mnt/data3 bs=100M count=1
umount /mnt

lvcreate -s -n vol4 vg0/vol1

mount -t xfs /dev/vg0/vol1 /mnt
dd if=/dev/zero of=/mnt/data4 bs=100M count=1
umount /mnt

lvs で見てみると、次のようにシンプールとボリュームのサイズがほとんど変わらないことがわかります。

lvs

LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert
thin vg0 twi-a-tz-- 1.00g 40.74
vol1 vg0 Vwi-a-tz-- 1.00g thin 40.10
vol2 vg0 Vwi---tz-k 1.00g thin vol1
vol3 vg0 Vwi---tz-k 1.00g thin vol1
vol4 vg0 Vwi---tz-k 1.00g thin vol1

複数のスナップショットがある状態で元ボリュームに書き込みが発生すると、CoW で複数のスナップショットに同じデータの書き込みが発生するかと思ったのですが(つまりスナップショットの数だけシンプールを消費する)、そんなこともないようです。


参考