Why LVM
LVM places three layers between raw disks and filesystems: physical volumes (PV) pool disk space, volume groups (VG) aggregate PVs, and logical volumes (LV) carve out named slices. This indirection lets you resize, span, and move data without repartitioning.
You partition a new server: /dev/sda1 for root, /dev/sda2 for /var, each a fixed size. Six months in, /var is 95% full and root has 40 GB free. With raw partitions you cannot move that space across — you would need to unmount, use a live rescue disk, resize with parted, and pray you did not corrupt the filesystem. A 3 AM outage drill nobody wants.
LVM exists to make this a 30-second operation. It inserts a thin layer of indirection between physical disks and filesystems — an abstraction that lets you resize, span multiple disks, and take consistent snapshots while the system is running.
After this lesson you can explain the three-layer LVM model (PV → VG → LV), create a basic LVM setup from scratch, inspect each layer with pvs/vgs/lvs, and articulate what you gain over raw partitions and why.
LVM has three layers. Each layer is a different unit of abstraction.
Raw disk or partition → Physical Volume (PV) → Volume Group (VG) → Logical Volume (LV) → filesystem.
- Physical Volume (PV): a disk or partition that has been initialised for LVM. It is the raw ingredient. Any block device works:
/dev/sdb,/dev/sdc1, even a software RAID device (/dev/md0). - Volume Group (VG): a pool that aggregates one or more PVs. The VG is where disk space lives. Adding a PV to a VG grows the pool. Removing a PV drains it.
- Logical Volume (LV): a named slice carved out of the VG’s pool. An LV looks like a block device (
/dev/myvg/data) and holds a filesystem. You grow, shrink, snapshot, and move LVs without touching partitions or disks directly.
# Check what LVM knows about each layer
pvs # list physical volumes
vgs # list volume groups
lvs # list logical volumes
# More detail
pvdisplay /dev/sdb
vgdisplay myvg
lvdisplay /dev/myvg/dataCreate a PV: initialise a block device for LVM.
# First, identify the disk (do NOT do this to a disk with data you need)
lsblk
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sdb 8:16 0 50G 0 disk
# sdc 8:32 0 50G 0 disk
# Initialise /dev/sdb as a physical volume
sudo pvcreate /dev/sdb
# Physical volume "/dev/sdb" successfully created.
# And /dev/sdc for a two-disk pool
sudo pvcreate /dev/sdc
# Physical volume "/dev/sdc" successfully created.
# Verify
sudo pvs
# PV VG Fmt Attr PSize PFree
# /dev/sdb lvm2 --- <50.00g <50.00g
# /dev/sdc lvm2 --- <50.00g <50.00g
# VG column is empty — not yet assigned to a grouppvcreate writes an LVM metadata header to the device. The disk’s data is effectively replaced — do this only on a blank or dedicated disk.
Create a VG: pool the PVs together.
# Create a volume group named "datavg" spanning both PVs
sudo vgcreate datavg /dev/sdb /dev/sdc
# Volume group "datavg" successfully created
sudo vgs
# VG #PV #LV #SN Attr VSize VFree
# datavg 2 0 0 wz--n- <99.99g <99.99g
# The VG now has ~100 GB of pooled space (2 × 50 GB)
# #LV is 0 — nothing carved out yet
# You can add more PVs to an existing VG later:
# sudo vgextend datavg /dev/sddThe VG name is how all subsequent LVM commands refer to this pool. Choose something meaningful: vg0, datavg, prod-vg. The name is embedded in device paths.
Create an LV: carve a named slice from the VG.
# Create a 30 GB logical volume named "appdata" in datavg
sudo lvcreate -L 30G -n appdata datavg
# Logical volume "appdata" created.
# Create a second LV using 20% of remaining free space
sudo lvcreate -l 20%FREE -n logs datavg
# Logical volume "logs" created.
sudo lvs
# LV VG Attr LSize
# appdata datavg -wi-a----- 30.00g
# logs datavg -wi-a----- 14.00g
# The LV is now a block device at two equivalent paths:
ls -l /dev/datavg/appdata
# lrwxrwxrwx /dev/datavg/appdata -> ../dm-0
ls -l /dev/mapper/datavg-appdata
# Same device, different symlink
# Format and mount the LV exactly like any block device:
sudo mkfs.ext4 /dev/datavg/appdata
sudo mkdir /mnt/appdata
sudo mount /dev/datavg/appdata /mnt/appdata
# Add to /etc/fstab using the device mapper path (stable):
# /dev/datavg/appdata /mnt/appdata ext4 defaults,nofail 0 2Understand what LVM buys you over raw partitions.
| Operation | Raw partitions | LVM |
|---|---|---|
| Grow a filesystem | Offline, risky resize | Online in most cases |
| Span multiple disks | Not possible without RAID | vgextend then lvextend |
| Consistent snapshot for backup | Not possible without fs support | lvcreate -s (copy-on-write) |
| Move data between disks | dd + unmount + repartition | pvmove online |
| Name your volumes | /dev/sda2 forever | /dev/vg0/postgres |
The naming benefit is underrated. /dev/myvg/postgres survives disk replacements and server migrations. /dev/sda2 is hardware topology baked into your config.
# See the complete picture: which PVs back which LVs
sudo pvdisplay --maps
# --- Physical volume ---
# PV Name /dev/sdb
# VG Name datavg
# ...
# --- Physical Segments ---
# Physical extent 0 to 7679:
# Logical volume /dev/datavg/appdata
# Logical extents 0 to 7679Setting up LVM on a fresh data disk, end-to-end.
# Scenario: new 200 GB disk /dev/sdb added to a web server.
# Goal: create a volume group with two LVs: one for app uploads, one for logs.
# 1. Confirm the disk is blank and the correct device
lsblk /dev/sdb
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sdb 8:16 0 200G 0 disk
# (no children = no partitions, safe to use)
# 2. Initialise as a PV (no partition needed — LVM can use the whole disk)
sudo pvcreate /dev/sdb
# Physical volume "/dev/sdb" successfully created.
# 3. Create the VG
sudo vgcreate webvg /dev/sdb
# Volume group "webvg" successfully created
# 4. Create LVs: 150 GB for uploads, 40 GB for logs
sudo lvcreate -L 150G -n uploads webvg
sudo lvcreate -L 40G -n logs webvg
# 5. Format both
sudo mkfs.xfs /dev/webvg/uploads
sudo mkfs.ext4 /dev/webvg/logs
# 6. Mount points + fstab
sudo mkdir -p /srv/uploads /var/log/app
sudo mount /dev/webvg/uploads /srv/uploads
sudo mount /dev/webvg/logs /var/log/app
# Add to /etc/fstab:
# /dev/webvg/uploads /srv/uploads xfs defaults,nofail 0 2
# /dev/webvg/logs /var/log/app ext4 defaults,nofail 0 2
# Test fstab before reboot
sudo mount -a
# 7. Verify
sudo lvs webvg
# LV VG Attr LSize
# logs webvg -wi-ao---- 40.00g
# uploads webvg -wi-ao---- 150.00g
# 'a' in Attr = active, 'o' = open (mounted)▸Why this works
Why use the whole disk (/dev/sdb) rather than a partition (/dev/sdb1) as a PV? Both work, but using the whole disk directly is simpler when the disk is dedicated to LVM — no partition table overhead, no confusion with partition numbering. The exception: if the disk might someday need to dual-boot or share space with a non-LVM filesystem, partition it first and make only the LVM partition a PV. Most server-dedicated data disks go directly to LVM.
▸Common mistake
A common mistake: running pvcreate on a disk that is already mounted or contains an active filesystem. LVM will warn you but historically has let you proceed on some versions. The result is corruption. Always verify with lsblk and mount | grep /dev/sdb that the target device is unmounted and not in use before calling pvcreate.
You have a volume group with 100 GB free, and you want to add a second 50 GB disk to increase the pool to 150 GB free. Which sequence of commands achieves this?
LVM inserts three layers between raw disks and filesystems. Physical volumes (PV) initialise block devices for LVM with pvcreate. Volume groups (VG) pool one or more PVs into a named disk-space pool with vgcreate; adding PVs later with vgextend grows the pool online. Logical volumes (LV) are named slices carved from a VG with lvcreate -L <size> -n <name> <vg>; they appear as block devices under /dev/<vg>/<lv> and hold filesystems like any partition. The payoff over raw partitions: resize online, span multiple disks, take snapshots, move data live, and name your storage semantically instead of by hardware slot.
Practice
Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.
Something unclear?
Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.