The Three Layers of LVM
LVM has exactly three concepts. Once these click, everything else follows naturally.
The full picture
Layer 1 — Physical Volume (PV)
A Physical Volume is a disk or partition that LVM has claimed. Nothing more. You’re just stamping it with an LVM header that says “I own this — don’t use it for regular partitions.”
pvcreate /dev/sda
LVM writes a small metadata header to the beginning of the disk. The rest of the space becomes a pile of Physical Extents (PEs) — fixed-size chunks (usually 4 MB each) that LVM uses as its basic unit of allocation. Think of PEs as the individual Lego bricks.
What a PV looks like:
/dev/sda ──────────────────────────────────────────────────
│ LVM header │ PE │ PE │ PE │ PE │ PE │ ... │
──────────────────────────────────────────────────
↑ 4 MB chunks, ~125,000 of them on a 500 GB disk
Key PV commands:
pvcreate /dev/sda # Create a PV from /dev/sda
pvs # List all PVs (quick summary)
pvdisplay # Detailed PV info
pvremove /dev/sda # Remove LVM from a disk (destroys data)
You can create a PV from a whole disk (/dev/sda) or from a single partition (/dev/sda1). Using whole disks is simpler and more flexible.
Layer 2 — Volume Group (VG)
A Volume Group is one or more PVs combined into a single pool. Once you have a VG, you forget about the individual disks — to LVM and to you, it’s just one big pile of space.
vgcreate vg_storage /dev/sda /dev/sdb /dev/sdc
This pools all three disks into vg_storage. LVM now has 3.5 TB to allocate as it sees fit. If you later plug in a fourth disk, you add it to the same VG — no reformatting, no data movement.
What a VG looks like internally:
vg_storage (3.5 TB)
┌──────────────────────────────────────────────────────────────────┐
│ PEs from /dev/sda │ PEs from /dev/sdb │ PEs from /dev/sdc │
│ ░░░░░░░░░░░░░░░░░░ │ ░░░░░░░░░░░░░░░░░░ │ ░░░░░░░░░░░░░░░░░░░░░ │
└──────────────────────────────────────────────────────────────────┘
500 GB 1 TB 2 TB
Key VG commands:
vgcreate vg_storage /dev/sda /dev/sdb # Create VG from PVs
vgextend vg_storage /dev/sdc # Add another disk later
vgs # Quick VG summary
vgdisplay vg_storage # Detailed info
vgremove vg_storage # Delete VG (destroys data)
Name your VG something meaningful (vg_data, vg_storage, ubuntu-vg). You’ll be typing it a lot.
Layer 3 — Logical Volume (LV)
A Logical Volume is a chunk of space carved from the VG — this is what you actually format with a filesystem (ext4, xfs) and mount.
lvcreate -L 200G -n lv_home vg_storage
This creates a 200 GB LV named lv_home from vg_storage. LVM finds 200 GB worth of PEs in the VG (from whichever disk has them free) and assigns them to this LV. To the filesystem above, it looks exactly like a regular block device at /dev/vg_storage/lv_home.
Logical Volumes can span multiple physical disks seamlessly:
lv_home (200 GB) — could be spread across sda and sdb — you don't care, LVM handles it
Key LV commands:
lvcreate -L 200G -n lv_home vg_storage # Create 200 GB LV
lvcreate -l 100%FREE -n lv_data vg_storage # Use all remaining space
lvs # Quick LV summary
lvdisplay # Detailed info
lvremove /dev/vg_storage/lv_home # Delete LV (destroys data)
Before and after LVM
Here’s why this matters in practice:
WITHOUT LVM WITH LVM
────────────────────────────────── ────────────────────────────────────
/dev/sda (500 GB) /dev/sda /dev/sdb /dev/sdc
┌────────┬────────┬────────┬──────┐ │ │ │
│/dev/ │/dev/ │/dev/ │/dev/ │ └────────┬┘ │
│sda1 │sda2 │sda3 │sda4 │ │ │
│/boot │/ │swap │/home │ ┌────────▼──────────▼────────┐
│500 MB │100 GB │4 GB │395 GB│ │ vg_storage │
└────────┴────────┴────────┴──────┘ │ 3.5 TB │
└──────────────────────────┬─┘
6 months later: │
/home is 90% full ┌──────┬──────────┬────────▼──┐
/ has 60 GB free │lv_ │lv_var │lv_home │
│root │100 GB │200 GB │
You can't resize /home — it's │100 GB│(growable)│(growable) │
physically fixed on the disk. └──────┴──────────┴───────────┘
Your only option: backup everything,
repartition, restore. Hours of work. 6 months later — /home 90% full?
lvextend -L +100G /dev/vg_storage/lv_home
resize2fs /dev/vg_storage/lv_home
Done. 30 seconds. No downtime.
The device path for LVs
When you create lv_home in vg_storage, it appears at two equivalent paths:
/dev/vg_storage/lv_home ← the symlink (easier to read)
/dev/mapper/vg_storage-lv_home ← the actual device (both work)
Use whichever you prefer — they point to the same thing.
Summary table
| Concept | Role | Command | Example result |
|---|---|---|---|
| Physical Volume | Marks a disk for LVM | pvcreate /dev/sda | /dev/sda is LVM-ready |
| Volume Group | Pools PVs into one | vgcreate vg_data /dev/sda /dev/sdb | vg_data = 1.5 TB |
| Logical Volume | Slices from the pool | lvcreate -L 200G -n lv_home vg_data | /dev/vg_data/lv_home exists |
| Format | Puts a filesystem on it | mkfs.ext4 /dev/vg_data/lv_home | Ready to mount |
| Mount | Makes it accessible | mount /dev/vg_data/lv_home /home | Files in /home |