Linux Disk Management: LVM Finally Explained So It Actually Makes Sense
“LVM terrified me for years. Physical volumes, volume groups, logical volumes, extents — nobody explains why this abstraction exists or what problem it solves. Until now.”
Ask most sysadmins to explain LVM and you’ll get a wall of terminology — physical volumes, volume groups, logical volumes, extents — recited without ever explaining why any of it exists. That’s exactly why so many people avoid LVM entirely and just use plain partitions, right up until the day they need to grow a filesystem live on a production server and discover there’s no way to do it without LVM.
This article explains LVM from the actual problem it solves outward: why fixed partitions fall short, how the PV → VG → LV hierarchy fixes it, and how to actually use it — creating volumes, resizing online, taking snapshots, and troubleshooting when things go sideways.
Table of Contents
- 01 — Why LVM Exists
- 02 — Basic LVM Operations
- 03 — Resizing Without Downtime
- 04 — LVM Snapshots
- 05 — LVM in Practice
- Cheat Sheet
- Key Takeaways
Installing LVM Tools
Most distros ship with LVM tools available but not always installed by default.
Debian/Ubuntu:
apt update
apt install -y lvm2RHEL/CentOS/Fedora:
dnf install -y lvm201 — Why LVM Exists
The problem with fixed partitions
A traditional partition (/dev/sda1, /dev/sda2, ...) is a fixed-size slice of a physical disk, defined at partition-table creation time. Once /var fills up because logs grew faster than anyone predicted, your options with plain partitions are painful:
Plain partitioning:
┌───────────────────────── /dev/sda ───────────────────────────┐
│ sda1 (/boot) │ sda2 (/) │ sda3 (/var) - FULL, stuck │
└──────────────────────────────────────────────────────────────┘
To grow sda3: need unallocated space directly after it,
or backup everything, repartition, and restore. Both risky, both need downtime.Even if there’s free space elsewhere on the disk, a plain partition can’t use it unless that space happens to be physically adjacent. And if the disk itself is full, adding a second physical disk doesn’t help a plain partition at all — a partition can’t span multiple physical disks.
What LVM adds: flexibility, snapshots, striping
LVM inserts a layer of abstraction between physical disks and the filesystems that sit on top of them. Instead of a filesystem living directly on a fixed partition, it lives on a logical volume that LVM can resize, move, and combine across physical disks without the filesystem needing to know or care where its underlying storage physically lives.
Get Suyash Adhikari’s stories in your inbox
Join Medium for free to get updates from this writer.
This unlocks:
- Online resizing — grow (and sometimes shrink) volumes without unmounting
- Spanning multiple disks — a single logical volume can pull space from several physical disks
- Snapshots — point-in-time copies for consistent backups, taken in seconds
- Striping — spread I/O across multiple disks for better throughput
PV → VG → LV hierarchy explained visually
Physical Volumes (PVs) Volume Group (VG) Logical Volumes (LVs)
───────────────────── ────────────────── ─────────────────────
/dev/sdb ──┐ ┌──▶ /dev/vg_data/lv_var (50GB)
├──▶ vgcreate ──▶ vg_data (500GB pool) ──┤
/dev/sdc ──┘ └──▶ /dev/vg_data/lv_home (200GB)
Raw disks/partitions A combined pool of Resizable "virtual disks"
contributed to the pool storage from all PVs carved from that pool,
each holding a filesystemThe key insight: a Volume Group is just a pool of storage capacity, aggregated from one or more Physical Volumes (whole disks or partitions). Logical Volumes are then carved out of that pool — and because it’s just a pool, LVs can grow, shrink, or move without caring which physical disk their blocks actually live on.
02 — Basic LVM Operations
pvcreate, vgcreate, lvcreate
Three commands, matching the three layers of the hierarchy:
# 1. Turn a raw disk/partition into a Physical Volume (PV)
pvcreate /dev/sdb
# 2. Create a Volume Group (VG) from one or more PVs
vgcreate vg_data /dev/sdb
# 3. Carve a Logical Volume (LV) out of the VG
lvcreate -L 50G -n lv_var vg_data-L 50G requests a fixed size; -l 100%FREE instead allocates all remaining free space in the VG:
lvcreate -l 100%FREE -n lv_home vg_datamkfs and mount
An LV is just block storage — it needs a filesystem before it’s usable, exactly like a regular partition:
mkfs.ext4 /dev/vg_data/lv_var
mkdir -p /mnt/var_new
mount /dev/vg_data/lv_var /mnt/var_newAdd to /etc/fstab for persistence across reboots:
/dev/vg_data/lv_var /var ext4 defaults 0 2Extending a logical volume online
This is the payoff for all the setup — growing a live, mounted filesystem with zero downtime:
lvextend -L +20G /dev/vg_data/lv_var
resize2fs /dev/vg_data/lv_var # ext4 — grows the filesystem to fill the LV
# or, for XFS:
xfs_growfs /var # note: XFS command takes the MOUNT POINT, not the devicepvdisplay, vgdisplay, lvdisplay
Inspect each layer:
pvdisplay # physical volumes: size, free space, which VG they belong to
vgdisplay # volume groups: total size, free space, number of LVs
lvdisplay # logical volumes: size, which VG, current statusQuicker summary views:
pvs # one-line-per-PV summary
vgs # one-line-per-VG summary
lvs # one-line-per-LV summary03 — Resizing Without Downtime
Extending: lvextend + resize2fs/xfs_growfs
The two-step pattern is always the same: grow the logical volume first, then grow the filesystem to match. The LV and the filesystem are tracked separately — growing one doesn’t automatically grow the other.
# Grow the LV by 10GB
lvextend -L +10G /dev/vg_data/lv_var
# Then grow the filesystem to use the new space
resize2fs /dev/vg_data/lv_var # ext4/ext3
xfs_growfs /var # XFS (mount point, not device!)Before: After lvextend: After resize2fs/xfs_growfs:
[LV: 50GB][FS: 50GB] ──────▶ [LV: 60GB][FS: 50GB] ──────▶ [LV: 60GB][FS: 60GB]
(unused 10GB, invisible (filesystem now
to the filesystem yet) sees all 60GB)Online shrink (ext4 only, careful)
Shrinking is fundamentally riskier than growing — data may exist in the space being removed, and it generally requires unmounting first (unlike growing, which can be done live for most filesystems):
umount /var
e2fsck -f /dev/vg_data/lv_var # mandatory before resizing ext4
resize2fs /dev/vg_data/lv_var 40G # shrink filesystem FIRST
lvreduce -L 40G /dev/vg_data/lv_var # then shrink the LV to match
mount /dev/vg_data/lv_var /varCritical order note: shrinking is the reverse of growing — shrink the filesystem before shrinking the LV, never after, or you risk truncating live data the filesystem still thinks it owns. XFS cannot be shrunk at all — if you need a smaller XFS volume, you must back up, recreate, and restore.
Adding a new disk to an existing VG
When the whole VG runs low on space, add another physical disk to the pool rather than to any single LV:
pvcreate /dev/sdc
vgextend vg_data /dev/sdc
vgs # confirm the VG now shows increased total/free spaceNow lvextend has more free space in the VG to draw from — the LVs sitting on top never needed to know a new physical disk was added.
04 — LVM Snapshots
Creating a snapshot: lvcreate --snapshot
A snapshot is a point-in-time, copy-on-write view of a logical volume — created almost instantly, regardless of how large the original volume is:
lvcreate --size 5G --snapshot --name lv_var_snap /dev/vg_data/lv_varThe snapshot only stores changes made after the snapshot was taken (copy-on-write) — the --size given is the space reserved for tracking those changes, not a full copy of the original volume.
Mounting a snapshot for backup
mkdir -p /mnt/var_snapshot
mount -o ro /dev/vg_data/lv_var_snap /mnt/var_snapshot
# Run your backup against the frozen, consistent point-in-time view
tar -czf /backups/var-backup.tar.gz -C /mnt/var_snapshot .
umount /mnt/var_snapshot
lvremove /dev/vg_data/lv_var_snapThis is the classic pattern for getting a consistent backup of a live, actively-written-to filesystem without stopping the service using it.
Snapshot size and overflow risk
Snapshot fills up if changes to the original exceed the reserved space:
Original LV: actively being written to
Snapshot: [reserved space for changes] ── if this fills before
you remove the snapshot,
the snapshot becomes INVALID
and unusableSize snapshots generously relative to expected write volume during their lifetime, and don’t leave them lying around indefinitely — a snapshot held open for days on a busy volume is a common way to run out of reserved space and lose the snapshot.
Thin provisioning
Traditional LVM snapshots pre-allocate space per snapshot. Thin provisioning instead creates a shared pool that multiple thin volumes and snapshots draw from on demand:
lvcreate --type thin-pool --size 100G --name thin_pool vg_data
lvcreate --thin --virtualsize 50G --name lv_thin1 vg_data/thin_poolThin provisioning lets you allocate volumes that add up to more than the physical pool size (betting that not everything will be fully used simultaneously) and makes snapshots dramatically cheaper to create in bulk — the tradeoff is that you must monitor pool usage carefully, since running out of actual physical space in an over-provisioned pool is a serious failure mode.
05 — LVM in Practice
Common layouts for web servers, databases
Typical web server VG layout: Typical database server VG layout:
vg_system vg_data
├── lv_root (20GB) → / ├── lv_pgdata (200GB) → /var/lib/postgresql
├── lv_var (50GB) → /var (logs) ├── lv_pgwal (20GB) → WAL, separate spindle/IOPS
├── lv_home (10GB) → /home └── lv_pgbackup (100GB) → local backup staging
└── lv_swap (8GB) → swapSeparating volatile, fast-growing paths like /var (logs) or database WAL onto their own LVs means a runaway log file fills its own volume — not the root filesystem the whole OS depends on.
LVM + dm-crypt for encrypted volumes
LVM composes cleanly with dm-crypt/LUKS for full-disk or per-volume encryption — the encryption layer sits either below LVM (encrypt the whole PV) or above it (encrypt individual LVs), depending on whether you need per-volume key separation:
# Encrypt the LV, then put a filesystem on top of the encrypted layer
cryptsetup luksFormat /dev/vg_data/lv_secure
cryptsetup luksOpen /dev/vg_data/lv_secure secure_data
mkfs.ext4 /dev/mapper/secure_data
mount /dev/mapper/secure_data /mnt/secureTroubleshooting: vgscan, pvscan after disk add
If LVM doesn’t automatically detect a newly attached disk or fails to activate volumes after a reboot or hardware change, force a rescan:
pvscan --cache # rescan for physical volumes
vgscan # rescan for volume groups
vgchange -ay # activate all volume groups foundThis sequence is also the standard first step when recovering a system where LVM volumes aren’t showing up as expected after moving disks between machines.
Cheat Sheet
# Setup
pvcreate /dev/sdb # disk → physical volume
vgcreate vg_data /dev/sdb # PV(s) → volume group
lvcreate -L 50G -n lv_var vg_data # VG → logical volume (fixed size)
lvcreate -l 100%FREE -n lv_home vg_data # VG → logical volume (all free space)
mkfs.ext4 /dev/vg_data/lv_var # filesystem on the LV
# Inspect
pvs / vgs / lvs # quick one-line summaries
pvdisplay / vgdisplay / lvdisplay # detailed views
# Grow (online, no downtime)
lvextend -L +10G /dev/vg_data/lv_var
resize2fs /dev/vg_data/lv_var # ext4
xfs_growfs /mount/point # XFS - mount point, not device
# Shrink (ext4 only, unmount first)
umount /var
e2fsck -f /dev/vg_data/lv_var
resize2fs /dev/vg_data/lv_var 40G # shrink FS first
lvreduce -L 40G /dev/vg_data/lv_var # then shrink LV
# Add capacity
pvcreate /dev/sdc
vgextend vg_data /dev/sdc
# Snapshots
lvcreate --size 5G --snapshot --name lv_var_snap /dev/vg_data/lv_var
mount -o ro /dev/vg_data/lv_var_snap /mnt/snap
lvremove /dev/vg_data/lv_var_snap
# Troubleshooting
pvscan --cache && vgscan && vgchange -ay
# Install
apt install -y lvm2 # Debian/Ubuntu
dnf install -y lvm2 # RHEL/CentOS/FedoraKey Takeaways
- LVM exists to solve what fixed partitions can’t: online resizing, spanning multiple physical disks, and fast point-in-time snapshots.
- The PV → VG → LV hierarchy means a Volume Group is just a pooled capacity source — Logical Volumes carved from it don’t care which physical disk their blocks live on.
- Growing a logical volume online is always two steps:
lvextendthe LV, thenresize2fs/xfs_growfsthe filesystem to actually use the new space. - Shrinking is riskier and order-sensitive: shrink the filesystem first, then the LV — never the reverse — and note that XFS cannot be shrunk at all.
vgextendafterpvcreateon a new disk grows the whole pool, giving every LV on that VG more room to grow into.- LVM snapshots are copy-on-write and near-instant, making them ideal for getting a consistent backup of a live, actively-written filesystem.
- Snapshots have their own reserved size and can become invalid if that space fills before you remove them — don’t leave snapshots open indefinitely.
- Thin provisioning trades simplicity for flexibility: it enables over-provisioning and cheap bulk snapshots, but requires careful monitoring of actual pool usage.
- Separating volatile paths (logs, database WAL) onto their own LVs contains a runaway filesystem-fill to that volume instead of taking down the whole system.









