LVM (Logical Volume Manager) is a logical volume management system for Linux that provides a layer of abstraction between physical disks and file systems. It lets you resize, move and administer your storage with a flexibility that is impossible to achieve with traditional partitioning.
Prerequisites
- Operating system: A Linux distribution (Debian 10+, Ubuntu 18.04+, CentOS 7+, RHEL 7+)
- Privileges: Root access or sudo privileges
- Disks: One or more available disks or partitions (unmounted)
- Knowledge: Basic notions of Linux administration and disk management
LVM Concepts
LVM is based on three stacked layers of abstraction. Understanding this architecture is essential before working with the commands.
The three LVM layers
- Physical Volumes (PV): The physical disks or partitions initialized for LVM. This is the lowest layer, directly tied to the hardware.
- Volume Groups (VG): Storage pools that group together one or more PVs. They form the reservoir of space from which logical volumes are carved out.
- Logical Volumes (LV): The volumes visible to the file system. They are carved out of a VG and can be resized dynamically.
Diagram of the LVM architecture
┌─────────────────────────────────────────────────────────┐
│ File systems │
│ /home /var /data │
├─────────────────────────────────────────────────────────┤
│ Logical Volumes (LV) │
│ lv_home lv_var lv_data │
├─────────────────────────────────────────────────────────┤
│ Volume Group (VG) │
│ vg_data │
├──────────────────┬──────────────────┬───────────────────┤
│ Physical Volume │ Physical Volume │ Physical Volume │
│ /dev/sda1 │ /dev/sdb1 │ /dev/sdc1 │
├──────────────────┼──────────────────┼───────────────────┤
│ Disk sda │ Disk sdb │ Disk sdc │
└──────────────────┴──────────────────┴───────────────────┘
Data is divided into Physical Extents (PE), fixed-size blocks (4 MB by default) that are the basic allocation unit of LVM.
Installation
The lvm2 package is required to use LVM. It is often pre-installed on server distributions.
# Debian / Ubuntu
sudo apt update && sudo apt install -y lvm2
# CentOS / RHEL / Fedora
sudo dnf install -y lvm2
# Check the installation
lvm version
If the
lvm version command displays the version information, LVM is correctly installed and ready to use.
Building the LVM infrastructure
Setting up LVM follows a precise order: you first initialize the PVs, then create a VG, and finally carve out the LVs.
Step 1: Create the Physical Volumes
Initialize the disks or partitions that will be managed by LVM:
# Initialize whole disks as PVs
sudo pvcreate /dev/sdb /dev/sdc
# Or initialize specific partitions
sudo pvcreate /dev/sdb1 /dev/sdc1
# Check the created PVs
sudo pvs
sudo pvdisplay
The
pvcreate command destroys all data present on the targeted disk or partition. Double-check the device name before running this command.
Step 2: Create the Volume Group
Group the PVs into a Volume Group:
# Create a VG named "vg_data" with two PVs
sudo vgcreate vg_data /dev/sdb /dev/sdc
# Check the created VG
sudo vgs
sudo vgdisplay vg_data
Step 3: Create the Logical Volumes
Carve out LVs from the VG according to your needs:
# Create a 50 GB LV
sudo lvcreate -L 50G -n lv_home vg_data
# Create a 20 GB LV
sudo lvcreate -L 20G -n lv_var vg_data
# Create an LV using all the remaining space
sudo lvcreate -l 100%FREE -n lv_data vg_data
# Check the created LVs
sudo lvs
sudo lvdisplay
The logical volumes are accessible through the path /dev/vg_data/lv_home or /dev/mapper/vg_data-lv_home.
Formatting and mounting
Logical volumes behave like traditional partitions. You need to format them and then mount them.
Format the volumes
# Format as ext4
sudo mkfs.ext4 /dev/vg_data/lv_home
sudo mkfs.ext4 /dev/vg_data/lv_var
# Format as XFS (recommended for large volumes)
sudo mkfs.xfs /dev/vg_data/lv_data
Temporary mount
# Create the mount points
sudo mkdir -p /mnt/home /mnt/var /mnt/data
# Mount the volumes
sudo mount /dev/vg_data/lv_home /mnt/home
sudo mount /dev/vg_data/lv_var /mnt/var
sudo mount /dev/vg_data/lv_data /mnt/data
# Check the mounts
df -hT | grep vg_data
Permanent mount via fstab
For automatic mounting at boot, add the entries to /etc/fstab:
# Retrieve the UUIDs of the volumes
sudo blkid /dev/vg_data/lv_home
sudo blkid /dev/vg_data/lv_var
sudo blkid /dev/vg_data/lv_data
# Add to /etc/fstab (replace the UUIDs)
# UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /home ext4 defaults 0 2
# UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /var ext4 defaults 0 2
# UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data xfs defaults 0 2
# Test the fstab configuration without rebooting
sudo mount -a
Always test with
mount -a after modifying /etc/fstab. An error in this file can prevent the system from booting.
Resizing volumes
Resizing is one of the main advantages of LVM. Extending is a safe operation; reducing requires precautions.
Extending a logical volume
# Add 10 GB to the volume
sudo lvextend -L +10G /dev/vg_data/lv_home
# Or extend to a total size of 80 GB
sudo lvextend -L 80G /dev/vg_data/lv_home
# Resize the ext4 file system
sudo resize2fs /dev/vg_data/lv_home
# For XFS (extension only, no reduction)
sudo xfs_growfs /mnt/data
# Shortcut: extend LV and file system in a single command
sudo lvextend -L +10G --resizefs /dev/vg_data/lv_home
Extending a logical volume and resizing an ext4 or XFS file system can be done on the fly, without unmounting the volume. This is the most common LVM operation in production.
Adding a new disk to the VG
# Initialize the new disk
sudo pvcreate /dev/sdd
# Extend the VG with the new PV
sudo vgextend vg_data /dev/sdd
# The space is now available for the LVs
sudo vgs
Reducing a logical volume
Reducing a logical volume can lead to data loss. Make a full backup before any reduction. XFS does not support reduction.
# 1. Unmount the volume
sudo umount /mnt/home
# 2. Check the integrity of the file system
sudo e2fsck -f /dev/vg_data/lv_home
# 3. Reduce the file system to 30 GB
sudo resize2fs /dev/vg_data/lv_home 30G
# 4. Reduce the logical volume to 30 GB
sudo lvreduce -L 30G /dev/vg_data/lv_home
# 5. Remount the volume
sudo mount /dev/vg_data/lv_home /mnt/home
LVM Snapshots
Snapshots let you capture the state of a volume at a precise instant, using the copy-on-write mechanism.
Creating a snapshot
# Create a 5 GB snapshot of the lv_home volume
sudo lvcreate -L 5G -s -n snap_home /dev/vg_data/lv_home
# Check the snapshot
sudo lvs
# Mount the snapshot read-only for verification
sudo mkdir -p /mnt/snapshot
sudo mount -o ro /dev/vg_data/snap_home /mnt/snapshot
The size of the snapshot determines how many changes it can absorb. If the snapshot fills up to 100%, it becomes unusable. Monitor its usage with
lvs and size it according to the expected change rate.
Restoring from a snapshot
# Unmount the original volume and the snapshot
sudo umount /mnt/home
sudo umount /mnt/snapshot
# Merge the snapshot with the original volume (restore)
sudo lvconvert --merge /dev/vg_data/snap_home
# Reactivate the volume (may require a reboot)
sudo lvchange -an /dev/vg_data/lv_home
sudo lvchange -ay /dev/vg_data/lv_home
# Remount the restored volume
sudo mount /dev/vg_data/lv_home /mnt/home
Deleting a snapshot
# Unmount the snapshot if it is mounted
sudo umount /mnt/snapshot
# Delete the snapshot
sudo lvremove /dev/vg_data/snap_home
Thin Provisioning
Thin provisioning lets you allocate more logical space than the physical space actually available. Space is only consumed when data is actually written.
Creating a thin pool
# Create a 100 GB thin pool in the VG
sudo lvcreate -L 100G --thinpool thin_pool vg_data
# Create thin volumes (over-provisioning possible)
sudo lvcreate -V 50G --thin -n thin_vol1 vg_data/thin_pool
sudo lvcreate -V 50G --thin -n thin_vol2 vg_data/thin_pool
sudo lvcreate -V 80G --thin -n thin_vol3 vg_data/thin_pool
# Total allocated: 180 GB for a 100 GB pool
# Only the space actually written is consumed
# Check the real usage
sudo lvs -a
With thin provisioning, if the pool's physical space runs out, all thin volumes become inaccessible. Set up active monitoring of the pool's fill rate and configure alerts at 80% usage.
Extending the thin pool
# Extend the data pool
sudo lvextend -L +50G vg_data/thin_pool
# Extend the metadata pool if necessary
sudo lvextend -L +1G vg_data/thin_pool_tmeta
Data migration
The pvmove command lets you migrate data from one physical disk to another without service interruption.
Migration with pvmove
# Migrate all data from sdb to sdd
sudo pvmove /dev/sdb /dev/sdd
# Migrate a specific logical volume
sudo pvmove -n lv_home /dev/sdb /dev/sdd
# Track progress in real time
sudo pvmove -i 5 /dev/sdb /dev/sdd
Replacing a disk
# 1. Add the new disk to the VG
sudo pvcreate /dev/sde
sudo vgextend vg_data /dev/sde
# 2. Migrate the data from the old disk
sudo pvmove /dev/sdb /dev/sde
# 3. Remove the old disk from the VG
sudo vgreduce vg_data /dev/sdb
# 4. Deactivate the PV of the old disk
sudo pvremove /dev/sdb
# The /dev/sdb disk can now be physically removed
The
pvmove migration works online. Applications keep accessing the data throughout the entire transfer.
RAID with LVM
LVM includes software RAID features that enable redundancy and improved performance without any external tool.
Mirroring (RAID 1)
# Create a mirrored volume across two disks
sudo lvcreate --type raid1 -m 1 -L 20G -n lv_mirror vg_data
# Check the synchronization status
sudo lvs -a -o +devices,sync_percent
# Convert an existing volume into a mirror
sudo lvconvert --type raid1 -m 1 /dev/vg_data/lv_home
Striping (RAID 0)
# Create a striped volume across 2 disks
# -i: number of stripes, -I: stripe size in KB
sudo lvcreate --type raid0 -i 2 -I 64 -L 40G -n lv_stripe vg_data
# Striping improves I/O performance by spreading
# writes across multiple disks simultaneously
Mirroring (RAID 1) provides redundancy at the cost of half the available space. Striping (RAID 0) doubles I/O performance but provides no redundancy: the loss of a single disk results in the loss of all data.
Monitoring
Regular monitoring of the LVM infrastructure is essential to anticipate space and performance problems.
Inspection commands
# Summary view of the Physical Volumes
sudo pvs
# Summary view of the Volume Groups
sudo vgs
# Summary view of the Logical Volumes
sudo lvs
# Detailed information
sudo pvdisplay /dev/sdb
sudo vgdisplay vg_data
sudo lvdisplay /dev/vg_data/lv_home
# Display the segments and physical layout
sudo pvs -o +pv_used,pv_free
sudo lvs -o +seg_pe_ranges,devices
Automated monitoring
# Basic monitoring script
#!/bin/bash
THRESHOLD=85
# Check the usage rate of each VG
for vg in $(vgs --noheadings -o vg_name); do
usage=$(vgs --noheadings -o vg_free_percent "$vg" | tr -d ' ')
used=$((100 - ${usage%.*}))
if [ "$used" -gt "$THRESHOLD" ]; then
echo "ALERT: VG $vg is ${used}% used" | logger -t lvm-monitor
fi
done
Integrate this script into a cron job or into your monitoring tool (Nagios, Zabbix, Prometheus) to be alerted before space runs out.
Hardening and best practices
- Consistent naming: Adopt a clear naming convention for VGs and LVs (e.g.,
vg_srv01,lv_mysql_data). - Do not allocate 100% of the space: Always keep 10 to 20% of free space in the VG for snapshots and emergencies.
- Configuration backups: Regularly export the LVM configuration with
vgcfgbackup. - Continuous monitoring: Watch the fill level of VGs, LVs and especially thin pools.
- Documentation: Document your LVM infrastructure (disks, VGs, LVs, mount points) in a wiki or a centralized configuration file.
- Test restores: Periodically verify that snapshots and backups are functional by restoring them in a test environment.
# Back up the VG configuration
sudo vgcfgbackup vg_data
# The backup files are in /etc/lvm/backup/
ls -la /etc/lvm/backup/
# Restore a configuration (in case of metadata corruption)
sudo vgcfgrestore vg_data
Troubleshooting
Here are the most common problems encountered with LVM and their solutions.
Volume Group not found
# Scan the disks to detect PVs
sudo pvscan
# Reactivate all VGs
sudo vgchange -ay
# If the VG is on an external disk, force the scan
sudo vgscan --mknodes
# Check that the dm-mod module is loaded
lsmod | grep dm
sudo modprobe dm-mod
Insufficient space in the VG
# Check the available space
sudo vgs -o +vg_free
# Identify the LVs that consume the most space
sudo lvs -o lv_name,lv_size,data_percent --sort -lv_size
# Possible solutions:
# 1. Add a new disk
sudo pvcreate /dev/sdX && sudo vgextend vg_data /dev/sdX
# 2. Reduce an underused LV (ext4 only)
sudo umount /path/mount
sudo e2fsck -f /dev/vg_data/lv_name
sudo resize2fs /dev/vg_data/lv_name 20G
sudo lvreduce -L 20G /dev/vg_data/lv_name
# 3. Delete a snapshot that is no longer needed
sudo lvremove /dev/vg_data/snap_old
Snapshot 100% full
# A full snapshot is automatically invalidated
# Check the status of the snapshots
sudo lvs -o lv_name,origin,snap_percent
# Delete the invalid snapshot
sudo lvremove /dev/vg_data/snap_invalid
# Recreate a larger snapshot
sudo lvcreate -L 10G -s -n snap_home /dev/vg_data/lv_home
Failing physical disk
# Check the status of the PVs
sudo pvs -o +pv_missing
# If a PV is marked "missing", migrate the remaining data
sudo pvmove --alloc anywhere /dev/sdb
# If pvmove fails (disk inaccessible), reduce the VG
sudo vgreduce --removemissing --force vg_data
The
vgreduce --removemissing --force command is a last-resort operation. The data stored on the failing disk will be lost. Always use RAID or backups to protect your critical data.
Conclusion
LVM is an essential tool for any serious Linux administration. It transforms storage management by offering a flexibility that traditional partitioning simply cannot provide:
- Live resizing of volumes without service interruption
- Snapshots for consistent backups and restore points
- Thin provisioning for optimal space allocation
- Online migration of data between physical disks
- Built-in software RAID for redundancy and performance
In production, adopt a proactive approach: monitor the available space, keep a margin of maneuver in your VGs, and regularly test your restore procedures. LVM is a powerful safety net, but only if you master it before you need it.
Comments