Manage Logical Volumes (LVM)
Master Logical Volume Management (LVM) for flexible storage. Create and manage physical volumes, volume groups, and logical volumes. Learn to extend, reduce, snapshot, and migrate storage dynamically.
📋 Table of Contents
🎯 Introduction to LVM
Logical Volume Manager (LVM) provides flexible disk management. Unlike traditional partitioning, LVM allows you to resize volumes, create snapshots, and move data between physical disks without downtime.
LVM Architecture
Physical Disks (/dev/sdb, /dev/sdc)
↓
Physical Volumes (PV) - pvcreate
↓
Volume Group (VG) - vgcreate (pool of storage)
↓
Logical Volumes (LV) - lvcreate (virtual partitions)
↓
File Systems (mkfs, mount)
LVM Components
| Component | Description | Example |
|---|---|---|
| Physical Volume (PV) | Physical disk or partition used by LVM | /dev/sdb1, /dev/sdc |
| Physical Extent (PE) | Smallest unit of storage (default 4MB) | 4MB blocks |
| Volume Group (VG) | Pool of PVs | vg_data, rhel |
| Logical Volume (LV) | Virtual partition created from VG | /dev/vg_data/lv_web |
| Logical Extent (LE) | PE mapped to LV | Same size as PE |
LVM Benefits
- Flexible Sizing: Resize volumes online (extend XFS/ext4, shrink ext4)
- Snapshots: Point-in-time backups for testing/rollback
- Striping: Spread data across disks for performance
- Mirroring: Data redundancy across physical volumes
- Migration: Move data between disks without downtime
Traditional: Fixed sizes, hard to resize, limited flexibility
LVM: Dynamic sizing, snapshots, pooled storage, easier management
💽 Physical Volumes (PV)
Creating Physical Volumes
# Initialize partition or disk as PV
sudo pvcreate /dev/sdb1
sudo pvcreate /dev/sdc
# Initialize multiple at once
sudo pvcreate /dev/sdb1 /dev/sdc /dev/sdd1
# Output example:
Physical volume "/dev/sdb1" successfully created.
Viewing Physical Volumes
# List all PVs
sudo pvs
# Output:
PV VG Fmt Attr PSize PFree
/dev/sda2 rhel lvm2 a-- 19.00g 0
/dev/sdb1 vgdata lvm2 a-- 5.00g 2.00g
# Detailed information
sudo pvdisplay
# Specific PV
sudo pvdisplay /dev/sdb1
# Show PE information
sudo pvs -v
sudo pvscan
Removing Physical Volumes
# Remove PV from VG first (pvmove if data exists)
sudo pvremove /dev/sdb1
# Output:
Labels on physical volume "/dev/sdb1" successfully wiped.
Use whole disks or partitions with Linux LVM type (8e for MBR, lvm flag for GPT). Label partitions with parted before creating PVs for clarity.
🗄️ Volume Groups (VG)
Creating Volume Groups
# Create VG from one PV
sudo vgcreate vg_data /dev/sdb1
# Create VG from multiple PVs
sudo vgcreate vg_data /dev/sdb1 /dev/sdc
# Specify PE size (default 4MB)
sudo vgcreate -s 8M vg_data /dev/sdb1
# Output:
Volume group "vg_data" successfully created
Viewing Volume Groups
# List all VGs
sudo vgs
# Output:
VG #PV #LV #SN Attr VSize VFree
rhel 1 2 0 wz--n- 19.00g 0
vg_data 2 1 0 wz--n- 9.99g 7.00g
# Detailed information
sudo vgdisplay
# Specific VG
sudo vgdisplay vg_data
# Show PVs in VG
sudo vgs -o +pv_name
Extending Volume Groups
# Add PV to existing VG
sudo vgextend vg_data /dev/sdd1
# Output:
Volume group "vg_data" successfully extended
# Verify
sudo vgs vg_data
Reducing Volume Groups
# Remove PV from VG (must be empty or use pvmove first)
sudo vgreduce vg_data /dev/sdd1
# Remove missing/failed PVs
sudo vgreduce --removemissing vg_data
Removing Volume Groups
# Remove VG (must delete all LVs first)
sudo vgremove vg_data
# Output:
Volume group "vg_data" successfully removed
Renaming Volume Groups
# Rename VG
sudo vgrename vg_data vg_backup
# Or by path
sudo vgrename /dev/vg_data vg_backup
📦 Logical Volumes (LV)
Creating Logical Volumes
# Create 2GB LV
sudo lvcreate -L 2G -n lv_web vg_data
# Create LV using all free space
sudo lvcreate -l 100%FREE -n lv_backup vg_data
# Create LV with specific extents
sudo lvcreate -l 512 -n lv_logs vg_data
# Output:
Logical volume "lv_web" created.
LV Naming
# LVs are accessed via:
/dev/VG_NAME/LV_NAME
/dev/vg_data/lv_web
# Or via mapper:
/dev/mapper/VG_NAME-LV_NAME
/dev/mapper/vg_data-lv_web
Viewing Logical Volumes
# List all LVs
sudo lvs
# Output:
LV VG Attr LSize Pool Origin Data%
lv_web vg_data -wi-a----- 2.00g
root rhel -wi-ao---- 17.00g
swap rhel -wi-ao---- 2.00g
# Detailed information
sudo lvdisplay
# Specific LV
sudo lvdisplay /dev/vg_data/lv_web
# Show all attributes
sudo lvs -a -o +devices
Creating Filesystem on LV
# Create XFS filesystem
sudo mkfs.xfs /dev/vg_data/lv_web
# Create ext4 filesystem
sudo mkfs.ext4 /dev/vg_data/lv_logs
# Mount
sudo mkdir /web
sudo mount /dev/vg_data/lv_web /web
# Verify
df -h /web
Removing Logical Volumes
# Unmount first
sudo umount /web
# Remove LV
sudo lvremove /dev/vg_data/lv_web
# Confirm:
Do you really want to remove active logical volume vg_data/lv_web? [y/n]: y
Logical volume "lv_web" successfully removed
Procedure: Complete LVM Setup
- Create partition with LVM type:
sudo parted /dev/sdb mkpart primary 1MiB 5GiB sudo parted /dev/sdb set 1 lvm on - Create Physical Volume:
sudo pvcreate /dev/sdb1 - Create Volume Group:
sudo vgcreate vg_data /dev/sdb1 - Create Logical Volume (2GB):
sudo lvcreate -L 2G -n lv_web vg_data - Create filesystem:
sudo mkfs.xfs /dev/vg_data/lv_web - Mount persistently:
sudo mkdir /web echo "/dev/vg_data/lv_web /web xfs defaults 0 2" | sudo tee -a /etc/fstab sudo mount -a - Verify:
df -h /web sudo lvs sudo vgs
📈 Extending Storage
Extending Logical Volumes
# Extend by specific size
sudo lvextend -L +1G /dev/vg_data/lv_web
# Extend to specific total size
sudo lvextend -L 5G /dev/vg_data/lv_web
# Extend using all free space
sudo lvextend -l +100%FREE /dev/vg_data/lv_web
# Extend and resize filesystem in one command
sudo lvextend -r -L +1G /dev/vg_data/lv_web
# Output:
Size of logical volume vg_data/lv_web changed from 2.00 GiB to 3.00 GiB.
Logical volume vg_data/lv_web successfully resized.
Extending File Systems
# After extending LV, extend the filesystem:
# XFS (must be mounted)
sudo xfs_growfs /web
# ext4 (can be mounted or unmounted)
sudo resize2fs /dev/vg_data/lv_web
# Check filesystem after extending
df -h /web
Extending Volume Groups
# If VG is out of space, add more PVs:
# Create new PV
sudo pvcreate /dev/sdc1
# Extend VG
sudo vgextend vg_data /dev/sdc1
# Now extend LV
sudo lvextend -L +5G /dev/vg_data/lv_web
sudo xfs_growfs /web
Procedure: Extend LV and Filesystem
- Check current size:
df -h /web sudo lvs /dev/vg_data/lv_web - Check VG free space:
sudo vgs vg_data - Extend LV by 2GB:
sudo lvextend -L +2G /dev/vg_data/lv_web - Extend filesystem (XFS):
sudo xfs_growfs /web - Verify:
df -h /web sudo lvs
Use lvextend -r to automatically resize the filesystem after extending the LV.
This works for both XFS and ext4: sudo lvextend -r -L +2G /dev/vg_data/lv_web
📉 Reducing Storage
XFS cannot be reduced! Only ext4 supports shrinking. Always backup data before reducing. Unmount the filesystem first. Risk of data loss if done incorrectly!
Reducing ext4 Logical Volumes
# IMPORTANT: Unmount first!
sudo umount /backup
# Check filesystem
sudo e2fsck -f /dev/vg_data/lv_backup
# Reduce filesystem first (to 3GB)
sudo resize2fs /dev/vg_data/lv_backup 3G
# Then reduce LV (to 3GB)
sudo lvreduce -L 3G /dev/vg_data/lv_backup
# WARNING prompt:
WARNING: Reducing active logical volume to 3.00 GiB.
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce vg_data/lv_backup? [y/n]: y
# Remount
sudo mount /dev/vg_data/lv_backup /backup
# Verify
df -h /backup
sudo lvs
Safe Reduction Steps
- Backup data (critical!)
- Unmount the filesystem
- Check filesystem integrity (e2fsck -f)
- Reduce filesystem first (resize2fs)
- Reduce LV to same or larger size
- Remount and verify
Alternative: lvreduce with -r
# Reduce LV and filesystem together (ext4 only)
sudo umount /backup
sudo lvreduce -r -L 3G /dev/vg_data/lv_backup
# This automatically:
# 1. Checks filesystem
# 2. Reduces filesystem
# 3. Reduces LV
XFS is optimized for performance and scalability, not shrinking. If you need to reduce an XFS volume, you must: backup data → destroy LV → create smaller LV → restore data.
📸 LVM Snapshots
Snapshots provide point-in-time copies of logical volumes. Perfect for backups before system changes, testing, or rollback scenarios.
Creating Snapshots
# Create snapshot (20% of original LV size for changes)
sudo lvcreate -L 1G -s -n lv_web_snap /dev/vg_data/lv_web
# Or use percentage
sudo lvcreate -l 20%ORIGIN -s -n lv_web_snap /dev/vg_data/lv_web
# Output:
Logical volume "lv_web_snap" created.
Viewing Snapshots
# List snapshots
sudo lvs
# Output shows snapshot with origin:
LV VG Attr LSize Pool Origin Data%
lv_web vg_data owi-aos--- 5.00g
lv_web_snap vg_data swi-a-s--- 1.00g lv_web 0.02
# Detailed snapshot info
sudo lvdisplay /dev/vg_data/lv_web_snap
Mounting Snapshots
# Mount snapshot for backup
sudo mkdir /snapshot
sudo mount -o ro /dev/vg_data/lv_web_snap /snapshot
# Backup from snapshot
sudo tar -czf /backup/web_backup.tar.gz -C /snapshot .
# Unmount
sudo umount /snapshot
Restoring from Snapshots
# Unmount original LV
sudo umount /web
# Merge snapshot back to original (reverts changes)
sudo lvconvert --merge /dev/vg_data/lv_web_snap
# Remount (after reboot or LV reactivation)
sudo mount /dev/vg_data/lv_web /web
Removing Snapshots
# Remove snapshot (keeps original LV)
sudo lvremove /dev/vg_data/lv_web_snap
# Confirm:
Do you really want to remove active logical volume vg_data/lv_web_snap? [y/n]: y
Procedure: Safe System Update with Snapshot
- Create snapshot before update:
sudo lvcreate -L 2G -s -n root_snap /dev/rhel/root - Perform system update:
sudo dnf update -y - Test the system. If problems occur, rollback:
# Boot to rescue mode or single user sudo umount / sudo lvconvert --merge /dev/rhel/root_snap sudo reboot - If update successful, remove snapshot:
sudo lvremove /dev/rhel/root_snap
Snapshot Best Practices
- Size snapshots at 20-30% of origin LV for typical changes
- Monitor snapshot usage (
lvsshows Data% column) - Remove snapshots after use to free space
- Snapshot fills = becomes invalid and is removed automatically
- Use snapshots for backups, not long-term storage
If snapshot runs out of space (Data% reaches 100%), it becomes invalid and is
automatically removed. Monitor with lvs and extend if needed:
sudo lvextend -L +500M /dev/vg_data/lv_web_snap
📝 Practice Questions
Question 1: What is the correct order for creating LVM storage?
Correct order: 1) pvcreate (Physical Volume), 2) vgcreate (Volume Group), 3) lvcreate (Logical Volume), 4) mkfs (filesystem), 5) mount. Think: physical → pool → virtual → format → use.
Question 2: Which filesystem can be extended but NOT reduced?
XFS can only be extended (xfs_growfs), never reduced. Use ext4 if you need shrinking capability. To "reduce" XFS, you must backup → delete → create smaller → restore.
Question 3: What command extends both LV and filesystem in one step?
The -r (or --resizefs) option automatically resizes the filesystem after extending the LV. Without -r, you must manually run xfs_growfs or resize2fs after lvextend.
Question 4: What happens when an LVM snapshot runs out of space?
When snapshot space fills (Data% = 100%), it becomes invalid and LVM automatically removes it. The original LV is not affected. Monitor with
lvs and extend
snapshot if needed: lvextend -L +500M /dev/vg/snap
Question 5: How do you create a 3GB logical volume named 'lv_data' in 'vg_app'?
Both commands are valid. Options order doesn't matter:
lvcreate -L SIZE -n NAME VG or lvcreate -n NAME -L SIZE VG.
The VG name must be last. Use -l for extents, -L for size.
Question 6: What must you do before reducing an ext4 logical volume?
Safe reduction: 1) Backup data, 2) umount, 3) e2fsck -f, 4) resize2fs to smaller size, 5) lvreduce to same or larger size. Or use
lvreduce -r to automate steps 3-5.
Never reduce LV before reducing filesystem = data loss!