Partitioning a disk used to be a decision you had to get right on day one. Make /var too small and you're stuck shuffling data around later. LVM (the Logical Volume Manager) removes most of that pain: you pool disks together and carve out volumes that can grow, shrink, move between disks and be snapshotted, usually without unmounting anything.
LVM is the default on many server installs (Ubuntu Server, RHEL, Fedora Server), so even if you've never set it up yourself, there's a good chance you're already using it. This post explains how the layers fit together and walks through the operations you'll actually need.
The three layers
LVM stacks three concepts on top of your disks:
- Physical volumes (PVs): disks or partitions initialised for LVM, such as
/dev/sdbor/dev/nvme0n1p3. - Volume groups (VGs): a pool made from one or more PVs. Think of it as one big virtual disk.
- Logical volumes (LVs): the "partitions" you create inside a VG. You put a filesystem on an LV and mount it like any other block device.
Under the hood, space is allocated in fixed-size chunks called extents (4 MiB by default), which is what lets LVM resize and move volumes so freely.
To see what's already on a machine:
sudo pvs sudo vgs sudo lvs lsblk
pvs, vgs and lvs give short summaries; pvdisplay, vgdisplay and lvdisplay show the full detail.
Creating a volume group and logical volumes
Say you've added a second disk, /dev/sdb, for data. Double-check the device name with lsblk first. The commands below destroy anything on it.
sudo pvcreate /dev/sdb sudo vgcreate data /dev/sdb sudo lvcreate -n www -L 50G data sudo lvcreate -n backups -l 60%FREE data
-L takes an absolute size; -l takes extents or a percentage, such as 60%FREE of whatever is left. Leaving some space unallocated in the VG is a good habit: it gives you room to grow any volume later and to take snapshots.
Logical volumes appear as /dev/data/www (also /dev/mapper/data-www). Format and mount them as usual:
sudo mkfs.ext4 /dev/data/www sudo mkdir -p /srv/www sudo mount /dev/data/www /srv/www
For a permanent mount, add a line to /etc/fstab:
/dev/data/www /srv/www ext4 defaults 0 2
The /dev/VG/LV path is stable across reboots, so you don't need UUIDs here the way you do with plain partitions.
Growing a volume (online)
This is the operation that makes LVM worth it. When /srv/www fills up and the VG has free space:
sudo lvextend -r -L +20G /dev/data/www
The -r (--resizefs) flag grows the filesystem in the same step, using resize2fs for ext4 or xfs_growfs for XFS. Both can grow while mounted, so there's no downtime. Use -l +100%FREE to give the volume everything that's left.
If the VG itself is full, add another disk to the pool first:
sudo pvcreate /dev/sdc sudo vgextend data /dev/sdc sudo lvextend -r -l +100%FREE /dev/data/www
Shrinking (carefully)
Shrinking is possible but riskier, and it depends on the filesystem:
- ext4 can shrink, but only while unmounted.
lvreduce -rhandles the filesystem resize for you. - XFS cannot shrink at all. The only way is backup, recreate and restore.
sudo umount /srv/www sudo lvreduce -r -L 40G /dev/data/www sudo mount /srv/www
Have a backup before you shrink anything. This is also why I prefer to allocate conservatively and grow later: growing is safe and online; shrinking isn't.
Snapshots
An LVM snapshot captures a volume's state at one moment. A classic snapshot needs its own space in the VG to store changed blocks:
sudo lvcreate -s -n www-snap -L 5G /dev/data/www
Two good uses:
- Consistent backups. Snapshot, mount the snapshot read-only, back it up, then remove it. The live volume keeps running throughout.
- Safe upgrades. Snapshot before a risky change. If it goes wrong, merge the snapshot back to roll the volume back:
sudo lvconvert --merge /dev/data/www-snap
If the volume is in use, the merge happens the next time it's activated (often at reboot). When things go fine, just delete the snapshot with sudo lvremove /dev/data/www-snap.
Watch the snapshot's fill level in lvs (the Data% column). A classic snapshot that runs out of space becomes invalid. Snapshots also slow writes on the origin volume, so treat them as short-lived tools, not a backup strategy. If you want long-lived, cheap snapshots, filesystems like Btrfs and ZFS do it better; see Btrfs vs ZFS.
Thin provisioning is the modern alternative: create a thin pool, put thin volumes inside it, and snapshots share the pool's space instead of needing a fixed size up front. It's worth learning once you're comfortable with the basics. Just monitor the pool so it never fills completely.
Moving data to a new disk without downtime
Replacing an ageing disk is where pvmove shines. Add the new disk to the VG, move all extents off the old one while everything stays mounted, then remove the old disk:
sudo pvcreate /dev/sdd sudo vgextend data /dev/sdd sudo pvmove /dev/sdb /dev/sdd sudo vgreduce data /dev/sdb sudo pvremove /dev/sdb
pvmove can take hours on large disks, but it's restartable. If it's interrupted, running pvmove again with no arguments resumes it.
LVM on top of LUKS
LVM and full-disk encryption fit together naturally. The common layout, used by many distro installers, is one LUKS-encrypted partition with LVM inside it, holding root, swap and home as logical volumes. You unlock once at boot, and every volume is encrypted.
sudo cryptsetup luksFormat /dev/nvme0n1p3 sudo cryptsetup open /dev/nvme0n1p3 cryptlvm sudo pvcreate /dev/mapper/cryptlvm sudo vgcreate system /dev/mapper/cryptlvm
From there you create LVs exactly as before. My post on full-disk encryption with LUKS and TPM2 covers the encryption side, including automatic unlocking with a TPM.
A few habits that save trouble
- Name VGs and LVs after their purpose (
data/www,data/db), notvg0/lv1. - Keep 10–20% of each VG free for growth and snapshots.
- Run
sudo vgsin your monitoring or a weekly check so you notice when a pool is getting full. - Back up
/etc/lvm/backup/. LVM writes metadata backups there automatically, andvgcfgrestorecan use them to recover a damaged layout.
Conclusion
LVM adds one layer of indirection between your disks and your filesystems, and that layer buys a lot of flexibility: grow volumes online, swap disks without downtime, and take quick snapshots before risky changes. Learn pvs/vgs/lvs, lvextend -r and pvmove, and you've covered most real-world use.
For containerised workloads, a dedicated LV for /var/lib/docker or your Podman storage keeps container data from filling the root filesystem; see Docker in Production. If you'd like a server built properly from the start, with sensible storage, backups and a web stack, I can help with that.
Comments (0)
No comments yet. Be the first to leave one!
Leave a Comment