LVM
関連記事
Wikipedia より:
- LVM は Linux カーネルの論理ボリュームマネージャです。ディスクドライブと大容量記憶装置を管理します。
目次
背景
LVM の構成要素
Logical Volume Management は Linux カーネルの device-mapper 機能を利用して基になっているディスクレイアウトから独立したパーティションのシステムを提供します。LVM を使うことで記憶領域を抽象化することで、(使っているファイルシステムで可能な限り)簡単にパーティションを拡大・縮小したり、物理ディスク上に十分な連続した領域があるかどうか心配することなく、また、fdisk したいディスクが使用中だったり (そしてカーネルが新旧どちらのパーティションテーブルを使っているのかわからなかったり) 他のパーティションをどけなくてはならないという問題に煩わされることなく、パーティションを追加・削除することが可能になります。これは厳密に言えば管理のしやすさの問題です: LVM はセキュリティを追加することはありません。しかしながら、私達の使っている他の2つの技術と上手く収まりがつきます。
LVM の基本的な構成要素は以下の通りです:
- 物理ボリューム (PV, Physical volume): ハードディスク上のパーティション (もしくはハードディスクそれ自体、ループバックファイル) です。これをまとめてボリュームグループを作ることができます。特別なヘッダーがあり物理エクステントに分割されます。物理ボリュームについてはハードドライブを構成するための大きなブロックとして考えて下さい。
- ボリュームグループ (VG, Volume group): ストレージボリューム(つまり一つのディスク)として使われる物理ボリュームの集まりです。ボリュームグループには論理ボリュームが含められます。ボリュームグループはハードドライブとして考えて下さい。
- 論理ボリューム (LV, Logical volume): ボリュームグループの中にある"仮想/論理パーティション"であり、物理エクステントで構成されます。論理ボリュームのことは通常のパーティションみたいなものと考えて下さい。
- 物理エクステント (PE, Physical extent): 論理ボリュームに割り当てるごとができるディスクの欠片 (通常 4MiB) です。物理エクステントはどのパーティションにも割り当てることが出来るディスクのパーツと考えて下さい。
例:
Physical disks Disk1 (/dev/sda): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |Partition1 50GB (Physical volume) |Partition2 80GB (Physical volume) | |/dev/sda1 |/dev/sda2 | |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | Disk2 (/dev/sdb): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |Partition1 120GB (Physical volume) | |/dev/sdb1 | | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ _ _|
LVM logical volumes Volume Group1 (/dev/MyStorage/ = /dev/sda1 + /dev/sda2 + /dev/sdb1): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |Logical volume1 15GB |Logical volume2 35GB |Logical volume3 200GB | |/dev/MyStorage/rootvol|/dev/MyStorage/homevol |/dev/MyStorage/mediavol | |_ _ _ _ _ _ _ _ _ _ _ |_ _ _ _ _ _ _ _ _ _ _ _ _ |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
利点
LVM には通常のハードドライブのパーティションを使うよりも幅広い柔軟性があります:
- 多数のディスクを一つの大きなディスクとして使えます。
- 複数のディスクにまたがる論理ボリュームを作れます。
- 小さな論理ボリュームを作成し、満杯になったら"動的に"リサイズできます。
- ディスクの順番と関係なく論理ボリュームをリサイズできます。VG における LV の位置に依存しないので、周辺に空き容量を取る必要がありません。
- オンラインで論理・物理ボリュームをリサイズ・作成・削除できます。ボリューム上のファイルシステムもリサイズする必要がありますが、オンラインリサイズをサポートしているファイルシステムもあります (ext4 など)。
- サービスによって使われている LV を、サービスを再起動する必要なく他のディスクへオンラインで移行することができます。
- スナップショットを使うことでファイルシステムのフローズンコピーをバックアップすることができます。サービスを落とす時間を最小限にできます。
- 透過的なファイルシステム暗号化や頻繁に使用されるデータのキャッシュなど、様々な device-mapper ターゲットをサポート。(LUKS によって暗号化された) 物理ディスクと LVM からなる環境を構築することで /, /home,/backup などの容量を簡単に変更したりできるようになります。起動時に何度もキーを入力する必要はありません。
欠点
- システムのセットアップに追加の手順が必要で、やや複雑。
- デュアルブートする場合、Windows は LVM をサポートしていません。Windows から LVM のパーティションにアクセスすることは不可能です。
始める
lvm2 パッケージがインストールされていることを確認してください。
設定
高度なオプション
(スナップショットに必要な)モニタリングが必要な場合は lvmetad を有効にしてください。/etc/lvm/lvm.conf
の use_lvmetad = 1
を設定することで有効にできます。現在はデフォルトで有効になっています。
自動的に有効になるボリュームを制限するには /etc/lvm/lvm.conf
の auto_activation_volume_list
を設定します。よくわからないときは、このオプションはコメントアウトしたままにしてください。
物理ボリュームを拡大する
物理ボリュームが存在するデバイスの容量を変更したら、次のコマンドを使って物理ボリュームを拡大する必要があります:
# pvresize DEVICE
例えば、mdadm RAID アレイ上の物理ボリュームを拡大するには:
# pvresize /dev/md0
論理ボリュームを拡大する
論理ボリュームにあるファイルシステムの空き容量を拡大するには、まず論理ボリュームを拡大させてから次に新しく作られた空き容量を使うようにファイルシステムを拡大させる必要があります。
lvextend
論理ボリュームを拡大するときに、使用できるコマンドは2つあります: lvextend
または lvresize
。
# lvextend -L +<size> <volume_group>/<logical_volume>
例えば:
# lvextend -L +20G VolGroup00/lvolhome
ボリュームグループにある全ての空き容量を使うようにしたい場合は、次のコマンドを使って下さい:
# lvextend -l +100%FREE <volume_group>/<logical_volume>
resize2fs
ext2,ext3, ext4 ファイルシステムのサイズを変更するには:
# resize2fs /dev/<volume_group>/<logical_volume>
例えば:
# resize2fs /dev/VolGroup00/lvolhome
物理ボリュームを縮小する
物理ボリュームを縮小する場合、使用するコマンドは:
# pvresize --setphysicalvolumesize MySize /dev/sdXA
上記のコマンドを実行すると以下のようなエラーが表示される場合があります:
/dev/sdAX: cannot resize to 25599 extents as later ones are allocated. 0 physical volume(s) resized / 1 physical volume(s) not resized
このメッセージは割り当て済みのエクステントが存在するために pvresize
が縮小を行うことができないと言っています。空き領域を全てボリュームの末端に移動するために、pvmove
コマンドを実行する必要があります。
物理エクステントを移動する
空きエクステントをボリュームの末端に移動する前に、# pvdisplay -v -m
を実行して物理セグメントを確認してください。下の例の場合、/dev/sdd1
に物理ボリュームがあり、vg1
というボリュームグループと backup という名前の論理ボリュームが存在します。
# pvdisplay -v -m
Finding all volume groups. Using physical volume(s) on command line. --- Physical volume --- PV Name /dev/sdd1 VG Name vg1 PV Size 1.52 TiB / not usable 1.97 MiB Allocatable yes PE Size 4.00 MiB Total PE 399669 Free PE 153600 Allocated PE 246069 PV UUID MR9J0X-zQB4-wi3k-EnaV-5ksf-hN1P-Jkm5mW --- Physical Segments --- Physical extent 0 to 153600: FREE Physical extent 153601 to 307199: Logical volume /dev/vg1/backup Logical extents 1 to 153599 Physical extent 307200 to 307200: FREE Physical extent 307201 to 399668: Logical volume /dev/vg1/backup Logical extents 153601 to 246068
空き領域がボリュームの中に分散してしまっていることがわかります。物理ボリュームを縮小するには、まず使用しているセグメントを先頭に移動しなくてはなりません。
最初の空きセグメントは 0 から 153600 で 153601 の空きエクステントがあります。このセグメントを最後の物理エクステントから最初のエクステントに移動します。コマンドは:
# pvmove --alloc anywhere /dev/sdd1:307201-399668 /dev/sdd1:0-92466
/dev/sdd1: Moved: 0.1 % /dev/sdd1: Moved: 0.2 % ... /dev/sdd1: Moved: 99.9 % /dev/sdd1: Moved: 100,0%
物理ボリュームのサイズを変更する
空き物理セグメントが全て最後の物理エクステントに移動できたら、# vgdisplay
を実行して空き PE を確認してください。
それから次のコマンドを再度実行します:
# pvresize --setphysicalvolumesize MySize /dev/sdXA
結果を確認:
# pvs
PV VG Fmt Attr PSize PFree /dev/sdd1 vg1 lvm2 a-- 1t 500g
パーティションのサイズを変更する
最後に、適当なパーティショニングツールを使ってパーティションのサイズを変更してください。
論理ボリュームを縮小する
基本的にファイルシステムは論理ボリュームと同じ大きさになっているので、まずファイルシステムを縮小してから次に論理ボリュームを縮小する必要があります。ファイルシステムによっては、先にファイルシステムをアンマウントする必要があるかもしれません。例えば ext3 が載った 15GB の論理ボリュームがあり 10G まで縮小したいとします。
まずファイルシステムを必要以上に縮小します。論理ボリュームを縮小するときにファイルシステムの末尾を偶発的に切り落とすことがないようにするためです:
# resize2fs /dev/VolGroup00/lvolhome 9G
それから論理ボリュームを縮小します:
# lvreduce -L 10G /dev/VolGroup00/lvolhome
最後に、論理ボリュームに残っている空き容量を満たすようにファイルシステムを拡大してください:
# resize2fs /dev/VolGroup00/lvolhome
論理ボリュームを削除する
まず、削除したい論理ボリュームの名前を確認してください。全ての論理ボリュームのリストを表示するには次のコマンドを使います:
# lvs
次に、削除する論理ボリュームのマウントポイントを確認して:
$ lsblk
アンマウントしてください:
# umount /<mountpoint>
最後に、論理ボリュームを削除してください:
# lvremove <volume_group>/<logical_volume>
例えば:
# lvremove VolGroup00/lvolhome
y
を入力することで実際に削除が実行されます。
必要に応じて /etc/fstab
を更新することを忘れないようにしましょう。
論理ボリュームの削除を確認するには root で lvs
を実行します (このセクションの一番最初を参照)。
ボリュームグループに物理ボリュームを追加する
まず使いたいブロックデバイスに新しい物理ボリュームを作成して、それからボリュームグループに追加してください:
# pvcreate /dev/sdb1 # vgextend VolGroup00 /dev/sdb1
これでボリュームグループの物理エクステントの総量が増えて、自由に論理ボリュームに割り当てることができるようになります。
ボリュームグループからパーティションを削除する
パーティション上に論理ボリュームを作成した場合、先に論理ボリュームを削除してください。
パーティションにあるデータを全て他のパーティションに移動する必要があります。ありがたいことに、LVM では簡単にできます:
# pvmove /dev/sdb1
データを特定の物理ボリュームに移したい場合は、pvmove
の二番目の引数に物理ボリュームを指定してください:
# pvmove /dev/sdb1 /dev/sdf1
次に物理ボリュームをボリュームグループから削除する必要があります:
# vgreduce myVg /dev/sdb1
もしくは、空の物理ボリュームを全て削除してください:
# vgreduce --all vg0
そして最後に、パーティションを他のことに使うために、LVM にパーティションを物理ボリュームとして扱わせないようにするには:
# pvremove /dev/sdb1
ボリュームグループを無効化する
次を実行してください:
# vgchange -a n my_volume_group
これでボリュームグループが無効になりボリュームグループが入っていたコンテナをアンマウントできるようになります。
スナップショット
説明
LVM を使うことで伝統的なバックアップよりも効率的なシステムのスナップショットを作ることができます。COW (copy-on-write) ポリシーを使うことによって効率化を実現しています。最初に作成したスナップショットには実際のデータの inode のハードリンクだけが含まれます。データに変更が加えられない間は、スナップショットには inode ポインターしかなくデータ自体は入りません。スナップショット先のファイルやディレクトリに変更が入ると、スナップショットによって古いコピーが参照され、新しいコピーは実行中のシステムによって参照されます。このため、35GB のデータがあるシステムでも 2GB 以下しか (オリジナルとスナップショット両方に) 変更を加えない限り、スナップショットに消費する空き容量は 2GB だけです。
設定
スナップショットの論理ボリュームは通常の論理ボリュームと同じように作れます:
# lvcreate --size 100M --snapshot --name snap01 /dev/mapper/vg0-pv
上記のボリュームでは、スナップショットボリュームが一杯になるまで、データの 100M まで変更を加えることができます。
次のコマンドを使うことによって変更が入った後の 'pv' 論理ボリュームを 'snap01' スナップショットが作られた状態まで戻すことが可能です:
# lvconvert --merge /dev/vg0/snap01
オリジナルの論理ボリュームが使用中の場合は、次のブート時にマージされます (LiveCD からマージすることもできます)。
マージが行われるとスナップショットはもう存在しなくなります。
また、複数のスナップショットを作成して、それぞれを自由にオリジナルの論理ボリュームにマージすることも可能です。
スナップショットはマウントして dd や tar を使うことでバックアップできます。dd で作られるバックアップファイルのサイズはスナップショットボリュームに入っているファイルのサイズになります。 復元は、スナップショットを作成してマウントして、バックアップをそこに書き込むか展開するだけです。そしてオリジナルのボリュームにマージしてください。
/etc/mkinitcpio.conf
の MODULES 変数に dm_snapshot モジュールを入れることが必要で、これがないとシステムが起動しなくなります。インストールしたシステムに既に記述してある場合は、次のコマンドでイメージを再生成してください:
# mkinitcpio -p linux
スナップショットは主にバックアップのためのファイルシステムのフローズンコピーを作るのに使われます; 2時間かかるバックアップはパーティションを直接バックアップするよりも一貫性のあるファイルシステムのイメージを提供します。
バックアップやロールバックのためシステム起動時に root ファイルシステムのスナップショットを自動的に作成する方法は LVM で root ファイルシステムのスナップショットを作成を見て下さい。
initramfs によって有効にならない LVM ボリュームがある場合は、lvm2 パッケージに入っている lvm-monitoring サービスを有効化してください。
キャッシュ
man より:
- キャッシュ論理ボリュームタイプは小さくて高速な LV を使うことで巨大で鈍重な LV のパフォーマンスを改善します。頻繁に使用されるブロックを高速な LV に保存することで高速化します。LVM は小さくて高速な LV のことをキャッシュプール LV と呼び、巨大で鈍重な LV のことをオリジン LV と呼びます。dm-cache (カーネルドライバー) の要件を満たすため、LVM はキャッシュプール LV をさらに2つのデバイスに分割します。キャッシュデータ LV とキャッシュメタデータ LV です。キャッシュデータ LV にはオリジン LV のデータブロックのコピーが保存されます。キャッシュメタデータ LV にはどこにデータブロックが保存されるかを示す情報が格納されます (例: オリジン LV にあるのかあるいはキャッシュデータ LV にあるのか)。最速かつ最強のキャッシュ論理ボリュームを作成しようと考えている場合はこれらの LV をよく知る必要があります。これらの LV は全て同一の VG に入っていなければなりません。
作成
高速なディスクに PV を作成して既存のボリュームグループに追加:
# vgextend dataVG /dev/sdx
自動メタデータを保存するキャッシュプールを sdb
に作成して、既存の論理ボリューム (dataLV) をキャッシュボリュームに変換:
# lvcreate --type cache --cachemode writethrough -L 20G -n dataLV_cachepool dataVG/dataLV /dev/sdx
キャッシュを大きくしたい場合、-L
パラメータに指定する容量を変えてください。
削除
上記で作成したキャッシュを削除したい場合:
# lvconvert --uncache dataVG/dataLV
上記のコマンドでキャッシュに留まっている書き込みが LV に適用され、それからキャッシュが削除されます。他のオプションについては man ページを参照。
シンプロビジョニング
From lvmthin(7):
- Blocks in a standard lvm(8) Logical Volume (LV) are allocated when the LV is created, but blocks in a thin provisioned LV are allocated as they are written. Because of this, a thin provisioned LV is given a virtual size, and can then be much larger than physically available storage. The amount of physical storage provided for thin provisioned LVs can be increased later as the need arises.
例: 仮想プライベートサーバを立てる
Here is the classic use case. Suppose you want to start your own VPS service, initially hosting about 100 VPSes on a single PC with a 930 GiB hard drive. Hardly any of the VPSes will actually use all of the storage they are allotted, so rather than allocate 9 GiB to each VPS, you could allow each VPS a maximum of 30 GiB and use thin provisioning to only allocate as much hard drive space to each VPS as they are actually using. Suppose the 930 GiB hard drive is /dev/sdb
. Here is the setup.
Prepare the volume group, MyVolGroup
.
# vgcreate MyVolGroup /dev/sdb
Create the thin pool LV, MyThinPool
. This LV provides the blocks for storage.
# lvcreate --type thin-pool -n MyThinPool -l 95%FREE MyVolGroup
The thin pool is composed of two sub-volumes, the data LV and the metadata LV. This command creates both automatically. But the thin pool stops working if either fills completely, and LVM currently does not support the shrinking of either of these volumes. This is why the above command allows for 5% of extra space, in case you ever need to expand the data or metadata sub-volumes of the thin pool.
For each VPS, create a thin LV. This is the block device exposed to the user for their root partition.
# lvcreate -n SomeClientsRoot -V 30G --thinpool MyThinPool MyVolGroup
The block device /dev/MyVolGroup/SomeClientsRoot
may then be used by a VirtualBox instance as the root partition.
シンスナップショットを使用してスペースを節約する
Thin snapshots are much more powerful than regular snapshots, because they are themselves thin LVs. See Red Hat's guide [1] for a complete list of advantages thin snapshots have.
Instead of installing Linux from scratch every time a VPS is created, it is more space-efficient to start with just one thin LV containing a basic installation of Linux:
# lvcreate -n GenericRoot -V 30G --thinpool MyThinPool MyVolGroup *** install Linux at /dev/MyVolGroup/GenericRoot ***
Then create snapshots of it for each VPS:
# lvcreate -s MyVolGroup/GenericRoot -n SomeClientsRoot
This way, in the thin pool there is only one copy the data common to all VPSes, at least initially. As an added bonus, the creation of a new VPS is instantaneous.
Since these are thin snapshots, a write operation to GenericRoot
only causes one COW operation in total, instead of one COW operation per snapshot. This allows you to update GenericRoot
more efficiently than if each VPS were a regular snapshot.
例: ゼロダウンタイムでストレージをアップグレードする
There are applications of thin provisioning outside of VPS hosting. Here is how you may use it to grow the effective capacity of an already-mounted file system without having to unmount it. Suppose, again, that the server has a single 930 GiB hard drive. The setup is the same as for VPS hosting, only there is only one thin LV and the LV's size is far larger than the thin pool's size.
# lvcreate -n MyThinLV -V 16T --thinpool MyThinPool MyVolGroup
This extra virtual space can be filled in with actual storage at a later time by extending the thin pool.
Suppose some time later, a storage upgrade is needed, and a new hard drive, /dev/sdc
, is plugged into the server. To upgrade the thin pool's capacity, add the new hard drive to the VG:
# vgextend MyVolGroup /dev/sdc
Now, extend the thin pool:
# lvextend -l +95%FREE MyVolGroup/MyThinPool
Since this thin LV's size is 16 TiB, you could add another 15.09 TiB of hard drive space before finally having to unmount and resize the file system.
トラブルシューティング
Arch-Linux のデフォルトの変更のためにする必要がある変更
/etc/lvm/lvm.conf
には use_lvmetad = 1
を設定する必要があります。現在はデフォルトで設定されています。lvm.conf.pacnew
ファイルがある場合は、この変更を適用してください。
LVM コマンドが機能しない
- 適切なモジュールをロードしてください:
# modprobe dm_mod
dm_mod
モジュールは自動的にロードされるはずです。そうならない場合は、次を試してみて下さい:
/etc/mkinitcpio.conf:
MODULES="dm_mod ..."
変更を適用するには initramfs を再生成する必要があります。
- lvm コマンドを次のように試してみて下さい:
# lvm pvdisplay
論理ボリュームが表示されない
既存の論理ボリュームをマウントしようとしても、lvscan
に表示されない場合、以下のコマンドによってボリュームを有効にすることができます:
# vgscan # vgchange -ay
リムーバブルメディア上の LVM
症状:
# vgscan Reading all physical volumes. This may take a while... /dev/backupdrive1/backup: read failed after 0 of 4096 at 319836585984: Input/output error /dev/backupdrive1/backup: read failed after 0 of 4096 at 319836643328: Input/output error /dev/backupdrive1/backup: read failed after 0 of 4096 at 0: Input/output error /dev/backupdrive1/backup: read failed after 0 of 4096 at 4096: Input/output error Found volume group "backupdrive1" using metadata type lvm2 Found volume group "networkdrive" using metadata type lvm2
病因:
- 最初にボリュームグループを無効にしないで外付けの LVM ドライブを取り外したこと。切断する前に、次を実行するようにしましょう:
# vgchange -an volume group name
治療:
- 外部ドライブのプラグを抜いて数分待って下さい:
# vgscan # vgchange -ay volume group name
連続している論理ボリュームのサイズ変更に失敗する
論理ボリュームを拡張すると以下のエラーが表示される場合:
" Insufficient suitable contiguous allocatable extents for logical volume "
明示的に連続するように割り当てるポリシー (オプション -C y
または --alloc contiguous
) を使って論理ボリュームが作成されており、ボリュームの近隣に連続したエクステントが存在しないのが原因です (リファレンス を参照)。
この問題を修正するには、論理ボリュームを拡張する前に、lvchange --alloc inherit <logical_volume>
で割り当てポリシーを変更してください。連続割り当てポリシーを使い続ける必要がある場合、空きエクステントが十分存在するディスク領域にボリュームを移動してください ([2] を参照)。
"grub-mkconfig" コマンドで "unknown filesystem" エラーが発生する
grub.cfg
を生成する前にスナップショットボリュームは削除するようにしてください。
シンプロビジョニングボリュームに root を配置する場合にタイムアウトが発生する
大量のスナップショットを使用した場合、thin_check
の実行時間が長くなるためルートデバイスがタイムアウトしてしまうことがあります。そのためブートローダーの設定に rootdelay=60
カーネルブートパラメータを追加してください。
シャットダウンが遅くなる
RAIDやスナップショット、シンプロビジョニングによってシャットダウンが遅くなる場合、lvm2-monitor.service
を起動・有効化してください。FS#50420 を参照。
参照
- SourceWare.org の LVM2 資料ページ
- Gentoo wiki の LVM 記事
- Ubuntu LVM ガイドパート 1 スナップショットに関するパート 2
- Red Hat: 論理ボリュームマネージャーの管理