Why
Without LVM the partition /dev/sda1 is a fixed slice of a disk. To grow
/home you have to move physical partitions. With LVM you add a disk to a
pool and grow the logical volume on the fly, without unmounting.
You also get snapshots, migration between disks, RAID, and thin provisioning.
Hierarchy
PV (Physical Volume) ← a regular partition or a whole disk
↓
VG (Volume Group) ← a pool of one or more PVs
↓
LV (Logical Volume) ← a virtual volume inside the VG, you put a filesystem on it
Building from scratch
# 1. Prepare the physical volumes (on partitions or a whole disk)
sudo pvcreate /dev/sdb1 /dev/sdc1
sudo pvs # list PVs
sudo pvdisplay /dev/sdb1 # details
# 2. Create a volume group from them
sudo vgcreate vg-data /dev/sdb1 /dev/sdc1
sudo vgs # list VGs
sudo vgdisplay vg-data
# 3. Carve out logical volumes
sudo lvcreate -L 50G -n web vg-data # a 50 GB volume "web"
sudo lvcreate -l 100%FREE -n logs vg-data # all the remaining space
sudo lvs # list LVs
sudo lvdisplay /dev/vg-data/web
# 4. Create a filesystem and mount it
sudo mkfs.ext4 /dev/vg-data/web
sudo mount /dev/vg-data/web /var/www
The names for fstab are /dev/<vg>/<lv> or /dev/mapper/<vg>-<lv>
(both point at the same device).
Growing online (the main feature)
# 1. Add one more disk to the VG
sudo pvcreate /dev/sdd1
sudo vgextend vg-data /dev/sdd1
# 2. Grow the LV
sudo lvextend -L +100G /dev/vg-data/web # +100 GB
sudo lvextend -l +100%FREE /dev/vg-data/logs # all free space
# 3. Grow the filesystem on top (WITHOUT unmounting)
sudo resize2fs /dev/vg-data/web # ext4
sudo xfs_growfs /var/www # xfs (by mount point!)
# ext4: all in one command
sudo lvextend -L +100G -r /dev/vg-data/web # -r = run resize2fs automatically
Shrinking (dangerous!)
Only ext4 / btrfs support it (xfs cannot). The order is REVERSED: shrink the filesystem first, then the LV.
sudo umount /var/www
sudo e2fsck -f /dev/vg-data/web
sudo resize2fs /dev/vg-data/web 30G
sudo lvreduce -L 30G /dev/vg-data/web
sudo mount /var/www
Get the order wrong and you lose data. Make a backup.
Snapshots
A COW snapshot is instant and uses space only for the changes:
# Snapshot for a backup: 5 GB of space for changes, named snap-web
sudo lvcreate -L 5G -s -n snap-web /dev/vg-data/web
# Use it (for example, a backup with rsync from a frozen state):
sudo mkdir /mnt/snap
sudo mount -o ro /dev/vg-data/snap-web /mnt/snap
rsync -av /mnt/snap/ /backup/web/
# Remove the snapshot
sudo umount /mnt/snap
sudo lvremove /dev/vg-data/snap-web
IMPORTANT: the snapshot breaks if the changes exceed the allocated space.
Monitor it: lvs, the Data% column.
Thin provisioning
Regular LVs take up their space right away. Thin LVs overcommit: you can create 5 volumes of 100 GB each with 200 GB of real space. They consume space as you write.
sudo lvcreate -L 200G -T vg-data/thin-pool # pool
sudo lvcreate -V 100G -T vg-data/thin-pool -n vm1 # a thin volume, 100G "virtually"
Dangerous if someone actually writes the data: dmesg starts complaining
and the volumes start to stall. Monitoring the pool usage is mandatory.
Migrating between disks online
Replace an old disk with a new one without downtime:
sudo pvcreate /dev/sde1
sudo vgextend vg-data /dev/sde1
sudo pvmove /dev/sdb1 # move off sdb1 onto the free PVs
sudo vgreduce vg-data /dev/sdb1
sudo pvremove /dev/sdb1
# Now sdb1 can be pulled out
Useful overview
sudo pvs && echo --- && sudo vgs && echo --- && sudo lvs
sudo lsblk # the tree shows the LVs
sudo lvs -o +devices # which PVs each LV sits on