LVM (Logical Volume Manager) puts a flexible layer between disks and filesystems. Instead of fixed partitions, you pool disks into a volume group and carve out logical volumes that you can grow, move between disks or snapshot later, often online. It’s standard on RHEL-family installs and common on dedicated servers with several drives.
The three layers
Disks / partitions → Physical Volumes (PV) /dev/sdb, /dev/sdc1
pooled into → Volume Group (VG) data-vg
divided into → Logical Volumes (LV) /dev/data-vg/www, /dev/data-vg/db
formatted with → Filesystems ext4, XFS
Install the tools
sudo apt install lvm2 # Debian/Ubuntu (often preinstalled)
sudo dnf install lvm2 # RHEL family
1. Create physical volumes
Use whole disks or partitions with the lvm type:
lsblk # identify the disks
sudo pvcreate /dev/sdb /dev/sdc
sudo pvs
2. Create a volume group
sudo vgcreate data-vg /dev/sdb /dev/sdc
sudo vgs
VG #PV #LV #SN Attr VSize VFree
data-vg 2 0 0 wz--n- <1.82t <1.82t
3. Create logical volumes
sudo lvcreate -n www -L 200G data-vg # fixed size
sudo lvcreate -n db -L 500G data-vg
sudo lvcreate -n backups -l 80%FREE data-vg # percentage of remaining space
sudo lvs
Leaving some free space in the VG is a good habit. You can then grow any LV later, and you have room for snapshots.
4. Format and mount
sudo mkfs.ext4 /dev/data-vg/www
sudo mkfs.xfs /dev/data-vg/db
sudo mkdir -p /var/www /var/lib/mysql
sudo mount /dev/data-vg/www /var/www
LV paths are stable, so they’re safe to use in fstab:
/dev/data-vg/www /var/www ext4 defaults,noatime 0 2
/dev/data-vg/db /var/lib/mysql xfs defaults,noatime 0 0
The same LV also appears as /dev/mapper/data--vg-www (hyphens in names are doubled there). See fstab.
Grow a logical volume
This is LVM’s main advantage:
sudo lvextend -r -L +50G /dev/data-vg/www
-r resizes the filesystem in the same step, online. Details and the “add a new disk” flow are in extend an LVM volume.
Add a disk to the pool
sudo pvcreate /dev/sdd
sudo vgextend data-vg /dev/sdd
The VG now has more free space for any LV.
Remove a disk from the pool
Move its data to other PVs, then remove it:
sudo pvmove /dev/sdb # online, can take hours for large disks
sudo vgreduce data-vg /dev/sdb
sudo pvremove /dev/sdb
This lets you replace an old drive without downtime.
LVM snapshots for consistent backups
A snapshot freezes an LV’s state at one moment. That’s great for backing up a database volume consistently:
sudo lvcreate -s -n db-snap -L 20G /dev/data-vg/db
sudo mkdir -p /mnt/db-snap
sudo mount -o ro,nouuid /dev/data-vg/db-snap /mnt/db-snap # nouuid needed for XFS
sudo tar -czf /backup/db-$(date +%F).tar.gz -C /mnt/db-snap .
sudo umount /mnt/db-snap
sudo lvremove -y /dev/data-vg/db-snap
Key points:
- The snapshot’s size (
-L 20G) only needs to hold changes made while it exists. If it fills up, the snapshot becomes invalid. WatchData%inlvs. - Remove snapshots promptly. They slow down writes to the origin.
- For databases, flush and lock briefly (
FLUSH TABLES WITH READ LOCKin MySQL) while creating the snapshot, or rely on crash recovery. - Snapshots live on the same disks. They’re not a backup until you copy the data elsewhere.
Thin provisioning (briefly)
Thin pools let you create LVs whose combined size exceeds the physical space, with space allocated as data is written. Snapshots of thin volumes are cheap. This is powerful but needs monitoring, because an overfilled thin pool is a serious failure. For most servers, regular (“thick”) LVs are simpler.
Useful commands
| Command | Shows |
|---|---|
pvs / pvdisplay |
Physical volumes |
vgs / vgdisplay |
Volume groups, free space |
lvs / lvdisplay |
Logical volumes, snapshot usage |
lsblk |
The whole stack as a tree |
lvrename, vgrename |
Rename |
lvremove |
Delete an LV (destroys data) |
LVM doesn’t protect against disk failure
A VG spread over two disks without RAID loses data when either disk fails. Combine LVM with RAID (mdadm underneath, or LVM’s own --type raid1) when redundancy matters. See software RAID with mdadm.
Quick reference
| Task | Command |
|---|---|
| Create PV | pvcreate /dev/sdb |
| Create VG | vgcreate vg /dev/sdb /dev/sdc |
| Create LV | lvcreate -n name -L 100G vg |
| Grow LV + fs | lvextend -r -L +50G /dev/vg/name |
| Add disk | pvcreate /dev/sdd && vgextend vg /dev/sdd |
| Snapshot | lvcreate -s -n snap -L 10G /dev/vg/name |
| Status | pvs; vgs; lvs |