Traditional Linux partitioning forces you to decide disk sizes at installation time. Need more space on /var six months later? You are looking at backup, repartition, and restore. LVM (Logical Volume Manager) eliminates this rigidity by adding an abstraction layer between physical disks and filesystems, allowing you to resize volumes, add storage, and take snapshots on a running system without downtime.

This guide covers the complete LVM workflow: creating physical volumes, grouping them into volume groups, allocating logical volumes, and performing the resize and snapshot operations that make LVM indispensable for server administration.

Prerequisites

Before you begin, make sure you have:

  • A Linux system with systemd (Ubuntu 20.04+, Debian 11+, RHEL/CentOS 8+, or similar)
  • Terminal access with sudo privileges
  • One or more available disks or partitions (unused block devices)
  • Basic understanding of Linux disk concepts (partitions, filesystems, mount points)

Warning: The commands in this guide will modify disk partition tables and create filesystems. Always verify device names carefully before running commands. Using the wrong device can destroy data.

LVM Architecture

LVM operates in three layers:

┌─────────────────────────────────────────┐
│          Filesystems (ext4, XFS)        │
├─────────────────────────────────────────┤
│      Logical Volumes (LV)               │
│      /dev/vg_name/lv_name               │
├─────────────────────────────────────────┤
│      Volume Groups (VG)                 │
│      Pool of storage from one or more   │
│      physical volumes                   │
├─────────────────────────────────────────┤
│      Physical Volumes (PV)              │
│      /dev/sdb, /dev/sdc, etc.           │
├─────────────────────────────────────────┤
│      Physical Disks / Partitions        │
└─────────────────────────────────────────┘
  • Physical Volume (PV): A disk or partition initialized for LVM use
  • Volume Group (VG): A pool of storage created from one or more PVs
  • Logical Volume (LV): A virtual partition carved from a VG, where you create filesystems

The key advantage is that VGs can span multiple physical disks, and LVs can be resized on the fly.

Installing LVM

LVM is pre-installed on most server distributions. Verify or install it:

# Debian/Ubuntu
sudo apt update && sudo apt install lvm2

# RHEL/Fedora/CentOS
sudo dnf install lvm2

# Verify installation
lvm version

Identifying Available Disks

Before creating physical volumes, identify your available block devices:

# List all block devices
lsblk

# Show detailed disk information
sudo fdisk -l

# Check which disks are already used by LVM
sudo pvs

Example lsblk output showing two unused disks:

NAME    MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda       8:0    0    50G  0 disk
├─sda1    8:1    0   512M  0 part /boot
└─sda2    8:2    0  49.5G  0 part /
sdb       8:16   0   100G  0 disk
sdc       8:32   0   100G  0 disk

In this example, sdb and sdc are available for LVM.

Creating Physical Volumes

Initialize the disks for LVM use:

sudo pvcreate /dev/sdb /dev/sdc

Output:

  Physical volume "/dev/sdb" successfully created.
  Physical volume "/dev/sdc" successfully created.

Verify the physical volumes:

# Summary view
sudo pvs

# Detailed view
sudo pvdisplay /dev/sdb

The pvs output shows:

  PV         VG     Fmt  Attr PSize   PFree
  /dev/sdb          lvm2 ---  100.00g 100.00g
  /dev/sdc          lvm2 ---  100.00g 100.00g

Note: You can also use partitions instead of whole disks. For example, sudo pvcreate /dev/sdb1 works if you prefer to partition the disk first with fdisk or parted. Using whole disks is simpler and recommended when the entire disk is dedicated to LVM.

Creating a Volume Group

Combine the physical volumes into a volume group:

sudo vgcreate vg_data /dev/sdb /dev/sdc

Output:

  Volume group "vg_data" successfully created

Verify the volume group:

# Summary view
sudo vgs

# Detailed view
sudo vgdisplay vg_data

The vgs output shows the combined storage:

  VG      #PV #LV #SN Attr   VSize   VFree
  vg_data   2   0   0 wz--n- 199.99g 199.99g

You now have a 200 GB pool of storage (from two 100 GB disks) that you can allocate flexibly.

Creating Logical Volumes

Allocate space from the volume group to create logical volumes:

# Create a 50 GB logical volume for applications
sudo lvcreate -L 50G -n lv_apps vg_data

# Create a 30 GB logical volume for databases
sudo lvcreate -L 30G -n lv_databases vg_data

# Create a volume using percentage of remaining free space
sudo lvcreate -l 50%FREE -n lv_logs vg_data

Common sizing options:

OptionMeaningExample
-L 50GExact size50 gigabytes
-L 500MExact size500 megabytes
-l 100%FREEAll remaining spaceUses everything left
-l 50%VGPercentage of VGHalf the volume group
-l 50%FREEPercentage of freeHalf the remaining space

Verify your logical volumes:

# Summary view
sudo lvs

# Detailed view
sudo lvdisplay /dev/vg_data/lv_apps

Formatting and Mounting

Create filesystems on the logical volumes:

# Format with ext4
sudo mkfs.ext4 /dev/vg_data/lv_apps
sudo mkfs.ext4 /dev/vg_data/lv_databases

# Or format with XFS (preferred for large volumes)
sudo mkfs.xfs /dev/vg_data/lv_logs

Create mount points and mount:

sudo mkdir -p /srv/apps /srv/databases /var/log/central

sudo mount /dev/vg_data/lv_apps /srv/apps
sudo mount /dev/vg_data/lv_databases /srv/databases
sudo mount /dev/vg_data/lv_logs /var/log/central

Persistent Mounting with fstab

Add entries to /etc/fstab so volumes mount automatically at boot:

# Get the UUIDs (more reliable than device paths)
sudo blkid /dev/vg_data/lv_apps
sudo blkid /dev/vg_data/lv_databases
sudo blkid /dev/vg_data/lv_logs

Add to /etc/fstab:

/dev/vg_data/lv_apps       /srv/apps         ext4 defaults 0 2
/dev/vg_data/lv_databases  /srv/databases    ext4 defaults 0 2
/dev/vg_data/lv_logs       /var/log/central  xfs  defaults 0 2

Tip: For LVM volumes, using the /dev/vg_name/lv_name path in fstab is common and reliable because LVM creates consistent device mapper symlinks. UUIDs also work if you prefer.

Test the fstab entries without rebooting:

sudo umount /srv/apps
sudo mount -a
df -h /srv/apps

Extending (Growing) a Logical Volume

This is LVM’s most valuable operation. When a volume runs out of space, extend it without downtime.

Extend with Free Space in the Volume Group

# Add 20 GB to the apps volume
sudo lvextend -L +20G /dev/vg_data/lv_apps

# Then resize the filesystem
# For ext4:
sudo resize2fs /dev/vg_data/lv_apps

# For XFS:
sudo xfs_growfs /srv/apps

Or do both in a single command:

# -r flag resizes the filesystem automatically
sudo lvextend -r -L +20G /dev/vg_data/lv_apps

Add a New Disk to the Volume Group

When the volume group itself runs out of space, add another physical disk:

# Initialize the new disk
sudo pvcreate /dev/sdd

# Add it to the existing volume group
sudo vgextend vg_data /dev/sdd

# Verify the new capacity
sudo vgs

Now you can extend logical volumes using the newly added space.

Reducing (Shrinking) a Logical Volume

Warning: Shrinking volumes carries data loss risk. Always back up before shrinking. XFS filesystems cannot be shrunk — only ext4 supports this operation.

For ext4 volumes:

# Unmount the volume first
sudo umount /srv/apps

# Check the filesystem
sudo e2fsck -f /dev/vg_data/lv_apps

# Shrink filesystem first, then the LV (-r does both)
sudo lvreduce -r -L 30G /dev/vg_data/lv_apps

# Remount
sudo mount /dev/vg_data/lv_apps /srv/apps

The -r flag ensures the filesystem is resized before the logical volume, preventing data corruption.

LVM Snapshots

Snapshots create a point-in-time copy of a logical volume using copy-on-write. They are ideal for backups on live systems.

Create a Snapshot

# Create a 5 GB snapshot of lv_databases
sudo lvcreate -L 5G -s -n snap_databases /dev/vg_data/lv_databases

The snapshot size (5 GB) represents the maximum amount of changed data that can be tracked. If the original volume changes more than 5 GB while the snapshot exists, the snapshot becomes invalid.

Use a Snapshot for Backup

# Mount the snapshot (read-only)
sudo mkdir -p /mnt/snap
sudo mount -o ro /dev/vg_data/snap_databases /mnt/snap

# Back up from the snapshot
sudo tar czf /backup/databases-$(date +%Y%m%d).tar.gz -C /mnt/snap .

# Unmount and remove the snapshot
sudo umount /mnt/snap
sudo lvremove /dev/vg_data/snap_databases

Restore from a Snapshot

# Merge a snapshot back into the original (rollback)
sudo lvconvert --merge /dev/vg_data/snap_databases

Note: The merge operation requires the original volume to be unmounted (or the system rebooted if the volume is the root filesystem). The snapshot is automatically deleted after the merge.

Monitoring and Maintenance

Check Space Usage

# Physical volume usage
sudo pvs -o +pv_used,pv_free

# Volume group summary
sudo vgs -o +vg_free

# Logical volume details
sudo lvs -o +lv_size,seg_count

Move Data Between Physical Volumes

If you need to decommission a disk:

# Move all extents off /dev/sdb to other PVs in the group
sudo pvmove /dev/sdb

# Remove the PV from the volume group
sudo vgreduce vg_data /dev/sdb

# Wipe the PV label
sudo pvremove /dev/sdb

Display Full Configuration

# Complete system overview
sudo lvm fullreport

Troubleshooting

Volume Group Not Found After Reboot

# Scan for all physical volumes
sudo pvscan

# Activate all volume groups
sudo vgchange -ay

# If found, update initramfs
sudo update-initramfs -u

Snapshot Running Out of Space

# Check snapshot usage
sudo lvs -o +snap_percent

# If approaching 100%, extend the snapshot
sudo lvextend -L +5G /dev/vg_data/snap_databases

If a snapshot reaches 100% capacity, it becomes invalid and must be removed.

Cannot Reduce a Volume

  • XFS: Cannot be shrunk. You must backup, recreate the LV at the smaller size, recreate the filesystem, and restore.
  • ext4: Must be unmounted first. Run e2fsck -f before any resize operation.
  • Volume still active: Use sudo umount or check for processes using the mount with lsof +D /mount/point.

LVM Commands Reference

CommandDescription
pvcreateInitialize a disk for LVM
pvs / pvdisplayShow physical volumes
vgcreateCreate a volume group
vgs / vgdisplayShow volume groups
vgextendAdd a PV to a VG
vgreduceRemove a PV from a VG
lvcreateCreate a logical volume
lvs / lvdisplayShow logical volumes
lvextend -rExtend a LV and resize filesystem
lvreduce -rShrink a LV and resize filesystem
lvcreate -sCreate a snapshot
lvremoveDelete a logical volume
pvmoveMove data off a physical volume

Summary

LVM is an essential tool for flexible disk management on Linux servers:

  • Three-layer architecture: Physical Volumes → Volume Groups → Logical Volumes
  • Extend volumes on the fly with lvextend -r — no downtime required
  • Add new disks to existing volume groups with vgextend to grow your storage pool
  • Use snapshots for consistent backups on live systems without stopping services
  • Always shrink filesystems before shrinking logical volumes to avoid data loss
  • LVM is not a replacement for RAID — use it on top of RAID for both flexibility and redundancy
  • Monitor snapshot usage to avoid invalidation at 100% capacity

For related topics, see our guides on ZFS Storage and Snapshots and Rsync Backup and Synchronization.