LVM Basics
Logical Volume Manager adds a flexible layer between raw partitions and filesystems - volumes that can be resized, spanned across multiple disks, and snapshotted, without being locked into fixed partition boundaries.
Partitioning (see Disk Partitioning) fixes a volume's size and location on one physical disk at creation time. LVM inserts an extra layer that removes that constraint - at the cost of one more layer to understand when something goes wrong.
Three layers
- Physical Volume (PV) - a raw disk or partition, initialized for LVM to use
- Volume Group (VG) - one or more PVs pooled together into a single chunk of storage, potentially spanning several physical disks
- Logical Volume (LV) - a slice of a VG, sized however you want, up to the VG's total capacity - this is what actually gets a filesystem and gets mounted, in place of a partition
[ disk1 ] [ disk2 ] <- physical volumes (PVs)
\ /
[ volume group ] <- pooled storage (VG)
/ \
[ lv-var ] [ lv-home ] <- logical volumes (LVs), each with its own filesystem
Creating the stack
sudo pvcreate /dev/sdb1 /dev/sdc1 # initialize two partitions as PVs
sudo vgcreate data-vg /dev/sdb1 /dev/sdc1 # pool them into one volume group
sudo lvcreate -n lv-projects -L 200G data-vg # carve out a 200G logical volume
sudo mkfs.ext4 /dev/data-vg/lv-projects # put a filesystem on it, same as a partition
sudo mount /dev/data-vg/lv-projects /mnt/projects
From here, /dev/data-vg/lv-projects is mounted and used exactly like
any partition - see Mounting and fstab
for making it persistent.
Viewing what exists
sudo pvs # physical volumes
sudo vgs # volume groups
sudo lvs # logical volumes, one compact line each
sudo lvdisplay /dev/data-vg/lv-projects # full detail on one LV
LV VG Attr LSize Pool Origin Data%
lv-projects data-vg -wi-ao---- 200.00g
(That compact table is lvs output; lvdisplay instead prints a
verbose block report per volume - LV Path, LV Size, LV Status,
and so on, one field per line.)
The main payoff: resizing without repartitioning
Growing a logical volume - and the filesystem on it - doesn't require unmounting or moving anything, as long as the volume group has free space (or another disk can be added to it):
sudo lvextend -L +50G /dev/data-vg/lv-projects # grow the LV by 50G
sudo resize2fs /dev/data-vg/lv-projects # grow an ext4 filesystem to match
sudo xfs_growfs /mnt/projects # grow an XFS filesystem to match (mounted, by mount point)
lvextend -r does both steps in one command on most modern LVM
versions. Shrinking is possible but far riskier (the filesystem must be
shrunk before the LV, and XFS can't be shrunk at all - see
Filesystem Types) - back up first if
it's ever necessary.
Adding an entirely new disk to existing capacity follows the same
pattern: pvcreate the new disk, vgextend the volume group with it,
then lvextend as above.
Snapshots
sudo lvcreate -s -n lv-projects-snap -L 10G /dev/data-vg/lv-projects
Creates a point-in-time, copy-on-write snapshot - cheap to create because it only stores blocks that change afterward, useful for taking a consistent backup of a volume that's actively being written to, or as a rollback point before a risky change. A snapshot isn't a substitute for an off-volume backup (see Backups): if the underlying disk fails, the snapshot is lost along with the original.
When it's worth the extra layer
Most distro installers offer LVM by default for the root filesystem, and it costs little to accept. Deliberately reaching for it matters most when you expect to resize volumes later, want to span storage across multiple physical disks as one pool, or want cheap snapshots without Btrfs. For a single disk with fixed, well-known partition sizes, plain partitioning is simpler to reason about and has one less layer to recover if something goes wrong.
Note that spanning a volume group across multiple disks (as above) provides no protection if one of them fails - see RAID Basics for actual redundancy, typically layered underneath LVM rather than instead of it.