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 で複数のスナップショットに同じデータの書き込みが発生するかと思ったのですが(つまりスナップショットの数だけシンプールを消費する)、そんなこともないようです。