LVM Setup and Management on Linux VPS
LVM (Logical Volume Manager) gives you far more flexibility than traditional Linux partitions. You can extend or shrink volumes online, add disks to an existing pool without reformatting, take instant snapshots for backups, and thin-provision storage — all while your services keep running.
Modern Linux VPS images (Ubuntu 22.04/24.04, Debian 12, AlmaLinux 9, Rocky Linux 9) often ship with LVM pre-installed when you select it at provisioning time. This guide walks you through everything from first install to live online expansion.
LVM Concepts — Three-Layer Architecture
Understanding these three layers makes every LVM command click into place:
| Layer | Name | Description |
|---|---|---|
| Bottom | Physical Volume (PV) | Raw disks or partitions: /dev/sdb, /dev/vdb |
| Middle | Volume Group (VG) | A pool that aggregates one or more PVs |
| Top | Logical Volume (LV) | Virtual partition you format and mount |
Key advantages over plain partitions: resize LVs online, add disks to VG and expand LVs immediately, snapshot before risky changes, thin-provision to overcommit disk space safely.
Step 1 — Install LVM2
Ubuntu/Debian:
sudo apt update && sudo apt install -y lvm2
sudo systemctl enable --now lvm2-lvmetad 2>/dev/null || true
AlmaLinux/Rocky Linux/CentOS:
sudo dnf install -y lvm2
sudo systemctl enable --now lvm2-monitor
which pvcreate.Step 2 — Create a Physical Volume (PV)
First, identify your available disks:
# List all disks and partitions
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE
# Inspect the new disk
sudo fdisk -l /dev/vdb
Assuming the new disk is /dev/vdb with no existing partitions:
# Initialize the entire disk as a PV (recommended)
sudo pvcreate /dev/vdb
# Or initialize a specific partition
sudo fdisk /dev/vdb # create a partition, set type to Linux LVM (8e)
sudo pvcreate /dev/vdb1
# Verify
sudo pvdisplay
sudo pvs
Step 3 — Create a Volume Group (VG)
# Create VG named "data-vg" from a single PV
sudo vgcreate data-vg /dev/vdb
# Or from multiple disks at once
sudo vgcreate data-vg /dev/vdb /dev/vdc
# Verify
sudo vgdisplay
sudo vgs
db-vg for database storage or web-vg for web content — it pays off when you manage multiple VGs later.Step 4 — Create a Logical Volume (LV)
# Create a 20 GB LV named "data-lv"
sudo lvcreate -L 20G -n data-lv data-vg
# Use all free space in the VG
sudo lvcreate -l 100%FREE -n data-lv data-vg
# Use 80% of VG (keep 20% for snapshots)
sudo lvcreate -l 80%VG -n data-lv data-vg
# Verify
sudo lvdisplay
sudo lvs
Step 5 — Format and Mount
# Format as ext4
sudo mkfs.ext4 /dev/data-vg/data-lv
# Or XFS (better for databases and large files)
sudo mkfs.xfs /dev/data-vg/data-lv
# Create mount point
sudo mkdir -p /data
# Mount
sudo mount /dev/data-vg/data-lv /data
# Persist in /etc/fstab
echo '/dev/data-vg/data-lv /data ext4 defaults 0 2' | sudo tee -a /etc/fstab
# Test fstab is valid
sudo mount -a && df -h /data
Extend a Logical Volume Online (Zero Downtime)
This is LVM's killer feature — resize storage while services are running:
# Add a new disk to an existing VG
sudo pvcreate /dev/vdc
sudo vgextend data-vg /dev/vdc
# Extend the LV by 10 GB
sudo lvextend -L +10G /dev/data-vg/data-lv
# Extend to use all remaining free space in VG
sudo lvextend -l +100%FREE /dev/data-vg/data-lv
# Resize the filesystem to use the new space (ext4)
sudo resize2fs /dev/data-vg/data-lv
# For XFS (filesystem must be mounted)
sudo xfs_growfs /data
# Verify
df -h /data
-r flag combines the lvextend and filesystem resize in one command: sudo lvextend -r -L +10G /dev/data-vg/data-lv. Works for both ext4 and XFS.LVM Snapshots for Backup
A snapshot is a copy-on-write freeze of an LV at a point in time — perfect before database upgrades or major changes:
# Create a 5 GB snapshot (COW buffer size)
sudo lvcreate -L 5G -s -n data-snap /dev/data-vg/data-lv
# Check snapshot fill percentage
sudo lvs -o +snap_percent
# Mount snapshot read-only
sudo mkdir -p /mnt/snapshot
sudo mount -o ro /dev/data-vg/data-snap /mnt/snapshot
# Archive the snapshot
sudo tar czf /backup/data-$(date +%Y%m%d).tar.gz /mnt/snapshot
# Unmount and remove snapshot when done
sudo umount /mnt/snapshot
sudo lvremove /dev/data-vg/data-snap
Thin Provisioning — Overcommit Disk Space
Thin provisioning lets you allocate more space than physically exists, only consuming real blocks on write:
# Create a thin pool of 50 GB
sudo lvcreate -L 50G --thinpool thin-pool data-vg
# Create a thin LV of 100 GB (overcommitted)
sudo lvcreate -V 100G --thin -n thin-lv data-vg/thin-pool
# Format and mount as usual
sudo mkfs.ext4 /dev/data-vg/thin-lv
sudo mount /dev/data-vg/thin-lv /data
Verify LVM is Working Correctly
# Quick overview of PVs, VGs, and LVs
sudo pvs && sudo vgs && sudo lvs
# Detailed VG info including free space
sudo vgdisplay data-vg
# Confirm LV is mounted
df -hT | grep lv
# Check LVM service status
sudo systemctl status lvm2-monitor
# Rescan for PVs/VGs (useful after adding a disk)
sudo pvscan
sudo vgscan
sudo lvscan
# Inspect device mapper entries
ls -la /dev/mapper/
sudo vgchange -ay to activate all VGs, or check /etc/lvm/lvm.conf for auto_activation_volume_list settings.Troubleshooting Common Errors
Error: "Can't open /dev/sdb exclusively. Mounted filesystem?"
The disk is still mounted or has an existing filesystem. You must unmount and wipe it before initializing as a PV.
# Check if the disk is mounted
lsblk /dev/sdb
findmnt /dev/sdb
# Unmount
sudo umount /dev/sdb
# Wipe existing signatures
sudo wipefs -a /dev/sdb
sudo pvcreate /dev/sdb
Error: "Insufficient free space: X extents needed, but only Y available"
The VG doesn't have enough free extents. Add a new disk to the VG first.
# Check VG free space
sudo vgs -o +vg_free
# Add a new disk
sudo pvcreate /dev/vdc
sudo vgextend data-vg /dev/vdc
# Retry the lvextend
sudo lvextend -l +100%FREE /dev/data-vg/data-lv
Error: "resize2fs: Bad magic number in super-block"
The filesystem is XFS, not ext4. Each filesystem type needs its own resize tool.
# Check the filesystem type
sudo blkid /dev/data-vg/data-lv
# For XFS: mount first, then grow
sudo mount /dev/data-vg/data-lv /data
sudo xfs_growfs /data
Error: "Snapshot percentage full — snapshot invalid"
The COW buffer is exhausted because more data was written to the origin LV than the snapshot size allows. The snapshot auto-invalidates.
# Monitor snapshot usage
sudo lvs -o +snap_percent
# If above 70-80%, recreate with a larger size
sudo umount /mnt/snapshot
sudo lvremove /dev/data-vg/data-snap
sudo lvcreate -L 10G -s -n data-snap /dev/data-vg/data-lv
Error: "device-mapper: remove ioctl failed: Device or resource busy"
The LV is still mounted. Unmount it before removing.
# Find processes using the mount point
sudo lsof /data
sudo fuser -m /data
# Force unmount
sudo umount -f /data
# Remove the LV
sudo lvremove /dev/data-vg/data-lv
Frequently Asked Questions
Is LVM worth using on a VPS, or is a plain partition enough?
LVM is the better choice for any production VPS where you anticipate disk growth or need snapshot-based backups. If disk size is fixed and you never need snapshots, a plain partition is simpler. For anything mission-critical with uptime requirements, LVM's online resize capability alone justifies the small setup overhead.
Do I need to restart services after extending an LV?
No. Once you run resize2fs (ext4) or xfs_growfs (XFS) on a mounted filesystem, running applications immediately see the new space — no restarts required. This is the main production advantage of LVM over repartitioning.
Can I use LVM snapshots as a real backup?
Snapshots are copy-on-write data on the same physical disk — if the disk fails, the snapshot goes with it. Use snapshots as a temporary freeze point to get a consistent dump, then ship that data off-server with rclone, restic, or BorgBackup. Snapshots are not a substitute for remote backup.