Configure and Manage LVM Storage¶
What is LVM?¶
LVM (Logical Volume Manager) is a flexible disk management system that sits between your physical hard drives and your filesystems. Think of it as a layer of abstraction that makes managing storage much easier and more flexible than traditional partitioning.
Why Use LVM?¶
Traditional Partitioning Problems: - Once you create a partition, resizing it is difficult and risky - You’re limited by physical disk boundaries - Moving data between disks requires backup and restore - You can’t easily combine multiple disks into one large volume
LVM Solutions: - Resize volumes easily (grow or shrink) while the system is running - Combine multiple physical disks into one large pool of storage - Move data between disks without downtime - Create snapshots for backups - Add more storage space without reformatting
LVM Architecture - The Three Layers¶
┌─────────────────────────────────────────┐
│ Filesystems (ext4, xfs, etc.) │ ← What users see
├─────────────────────────────────────────┤
│ Logical Volumes (LV) │ ← Virtual partitions
│ /dev/vg01/lv_data │
│ /dev/vg01/lv_web │
├─────────────────────────────────────────┤
│ Volume Groups (VG) │ ← Storage pool
│ vg01: combines all PVs │
├─────────────────────────────────────────┤
│ Physical Volumes (PV) │ ← Physical disks/partitions
│ /dev/sdb, /dev/sdc, /dev/sdd │
└─────────────────────────────────────────┘
1. Physical Volumes (PV) - Your actual hard drives or partitions - Example: /dev/sdb, /dev/sdc1 - These are the raw storage devices you’ll use
2. Volume Groups (VG) - A pool of storage made from one or more PVs - Example: vg_data (combining /dev/sdb and /dev/sdc) - Think of it as a big bucket of storage space
3. Logical Volumes (LV) - Virtual partitions created from VG space - Example: lv_database, lv_webserver - These are what you format and mount, just like regular partitions
Physical Volume Management¶
What Are Physical Volumes?¶
Physical Volumes are your actual hard drives or partitions that have been prepared for use with LVM. Before you can use a disk with LVM, you must initialize it as a Physical Volume.
pvcreate - Initialize a Disk for LVM¶
What it does: Prepares a disk or partition to be used with LVM by writing special metadata.
Why use it: This is always your first step when adding a new disk to LVM.
Examples:
# Initialize an entire disk for LVM
pvcreate /dev/sdb
# Output: Physical volume "/dev/sdb" successfully created.
# Initialize a partition (you must create the partition first with fdisk/parted)
pvcreate /dev/sdc1
# Initialize multiple disks at once
pvcreate /dev/sdb /dev/sdc /dev/sdd
Real-world scenario: You’ve just added a new 500GB disk (/dev/sdb) to your server. Before you can use it with LVM:
pvcreate /dev/sdb
pvs - Quick Overview of Physical Volumes¶
What it does: Shows a simple summary of all Physical Volumes on your system.
Why use it: Quick check to see what PVs exist, their size, and which VG they belong to.
Example:
pvs
Output:
PV VG Fmt Attr PSize PFree
/dev/sdb vg01 lvm2 a-- 100.00g 50.00g
/dev/sdc vg01 lvm2 a-- 200.00g 200.00g
/dev/sdd vg02 lvm2 a-- 500.00g 100.00g
What this tells you: - /dev/sdb and /dev/sdc are both part of vg01 - /dev/sdb has 50GB free out of 100GB total - /dev/sdc is completely unused (200GB free out of 200GB)
pvdisplay - Detailed Information About Physical Volumes¶
What it does: Shows detailed information about one or all Physical Volumes.
Why use it: When you need detailed information like UUID, exact sizes, or troubleshooting.
Examples:
# Show details for all PVs
pvdisplay
# Show details for a specific PV
pvdisplay /dev/sdb
Output example:
--- Physical volume ---
PV Name /dev/sdb
VG Name vg01
PV Size 100.00 GiB
Allocatable yes
PE Size 4.00 MiB
Total PE 25599
Free PE 12799
Allocated PE 12800
PV UUID abc123-def456-...
What this means: - This PV is part of vg01 - Total size is 100GB - About half is used (12800 PE allocated out of 25599 total) - PE (Physical Extent) is the smallest unit of space LVM uses (4MB blocks)
pvmove - Move Data Off a Physical Volume¶
What it does: Moves all data from one Physical Volume to other PVs in the same Volume Group.
Why use it: You want to remove a disk from your system (maybe it’s failing, or you’re upgrading).
Example:
# Move all data from /dev/sdb to other disks in the VG
pvmove /dev/sdb
# Move data from /dev/sdb to a specific disk
pvmove /dev/sdb /dev/sdc
Real-world scenario: Your /dev/sdb disk is showing SMART errors and needs to be replaced:
# Step 1: Move all data off the failing disk
# (This can take hours for large disks!)
pvmove /dev/sdb
# Step 2: Remove it from the VG
vgreduce vg01 /dev/sdb
# Step 3: Remove PV label
pvremove /dev/sdb
# Step 4: Physically replace the disk
# Step 5: Add the new disk
pvcreate /dev/sdb
vgextend vg01 /dev/sdb
pvremove - Remove Physical Volume¶
What it does: Removes the LVM label from a disk, making it no longer a Physical Volume.
Why use it: Clean up after removing a disk from LVM, or reusing a disk for something else.
Example:
# Remove PV label (must not be in use!)
pvremove /dev/sdb
Important: The PV must not be part of any VG. Remove it from the VG first with vgreduce.
Volume Group Management¶
What Are Volume Groups?¶
A Volume Group is a storage pool created from one or more Physical Volumes. Think of it as combining multiple hard drives into one big pool of storage that you can then divide up however you want.
vgcreate - Create a New Volume Group¶
What it does: Creates a new storage pool from one or more Physical Volumes.
Why use it: This is how you combine disks into a unified storage pool.
Examples:
# Create a VG from a single PV
vgcreate vg_data /dev/sdb
# Create a VG from multiple PVs (combining 3 disks into one pool)
vgcreate vg_data /dev/sdb /dev/sdc /dev/sdd
# Create VG with a specific extent size (16MB instead of default 4MB)
# Larger extents = slightly less overhead for very large volumes
vgcreate -s 16M vg_bigdata /dev/sdb /dev/sdc
Real-world scenario: You have three 1TB disks and want to create one large storage pool:
# Step 1: Initialize all disks
pvcreate /dev/sdb /dev/sdc /dev/sdd
# Step 2: Create VG combining all three (total ~3TB)
vgcreate vg_storage /dev/sdb /dev/sdc /dev/sdd
# Step 3: Verify
vgs vg_storage
# Shows: vg_storage with ~3TB total size
vgs - Quick Overview of Volume Groups¶
What it does: Shows a summary of all Volume Groups.
Why use it: Quick check of VG size, free space, and how many PVs/LVs they contain.
Example:
vgs
Output:
VG #PV #LV #SN Attr VSize VFree
vg_data 2 3 0 wz--n- 300.00g 50.00g
vg_backup 1 1 0 wz--n- 500.00g 400.00g
What this tells you: - vg_data has 2 PVs, 3 LVs, 300GB total, 50GB free - vg_backup has 1 PV, 1 LV, 500GB total, 400GB free
vgdisplay - Detailed Volume Group Information¶
What it does: Shows detailed information about Volume Groups.
Why use it: Get complete details including UUIDs, extent information, and which LVs exist.
Example:
# Show all VGs in detail
vgdisplay
# Show specific VG
vgdisplay vg_data
Output example:
--- Volume group ---
VG Name vg_data
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 15
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 3
Open LV 2
Max PV 0
Cur PV 2
Act PV 2
VG Size 299.99 GiB
PE Size 4.00 MiB
Total PE 76798
Alloc PE / Size 64000 / 250.00 GiB
Free PE / Size 12798 / 49.99 GiB
VG UUID xyz789-abc123-...
vgextend - Add Storage to a Volume Group¶
What it does: Adds a Physical Volume to an existing Volume Group, increasing available space.
Why use it: When you need more space and add a new disk to the system.
Example:
# Add a new disk to existing VG
pvcreate /dev/sdd
vgextend vg_data /dev/sdd
Real-world scenario: Your vg_data is running low on space. You add a new 500GB disk:
# Step 1: Initialize new disk
pvcreate /dev/sdd
# Output: Physical volume "/dev/sdd" successfully created.
# Step 2: Add to existing VG
vgextend vg_data /dev/sdd
# Output: Volume group "vg_data" successfully extended
# Step 3: Verify new space available
vgs vg_data
# VSize will now show 500GB more space
vgreduce - Remove a Disk from Volume Group¶
What it does: Removes a Physical Volume from a Volume Group.
Why use it: Before removing a disk or decommissioning storage.
Example:
# First, move data off the disk
pvmove /dev/sdd
# Then remove it from the VG
vgreduce vg_data /dev/sdd
# Finally, remove PV label
pvremove /dev/sdd
Real-world scenario: You want to remove /dev/sdd from vg_data:
# Check what's on it first
pvs /dev/sdd
# Move any data to other disks in the VG
pvmove /dev/sdd
# This may take a while...
# Remove from VG
vgreduce vg_data /dev/sdd
# Output: Volume group "vg_data" successfully reduced
# Clean up
pvremove /dev/sdd
vgremove - Delete a Volume Group¶
What it does: Completely removes a Volume Group.
Why use it: Cleaning up or starting over with storage configuration.
Example:
# Remove all LVs first
lvremove /dev/vg_data/lv_web
lvremove /dev/vg_data/lv_db
# Then remove the VG
vgremove vg_data
Warning: This is destructive! All Logical Volumes must be removed first.
Logical Volume Management¶
What Are Logical Volumes?¶
Logical Volumes are virtual partitions created from Volume Group space. They’re what you actually format with filesystems and mount. Unlike traditional partitions, they can be easily resized, moved, and snapshotted.
lvcreate - Create a Logical Volume¶
What it does: Creates a new Logical Volume from available space in a Volume Group.
Why use it: This creates the “partition” you’ll format and use for storing data.
Examples:
# Create a 20GB logical volume named "lv_web"
lvcreate -L 20G -n lv_web vg_data
# Create an LV using 50% of the VG
lvcreate -l 50%VG -n lv_database vg_data
# Create an LV using ALL free space
lvcreate -l 100%FREE -n lv_backup vg_data
# Create an LV with exactly 5000 extents (size depends on PE size)
lvcreate -l 5000 -n lv_app vg_data
Real-world scenario - Setting up a web server:
# You have vg_data with 500GB free space
# Create volumes for different purposes:
# 50GB for web files
lvcreate -L 50G -n lv_web vg_data
# 100GB for database
lvcreate -L 100G -n lv_database vg_data
# 30GB for logs
lvcreate -L 30G -n lv_logs vg_data
# Use remaining space for backups
lvcreate -l 100%FREE -n lv_backup vg_data
# Verify
lvs vg_data
Complete workflow - From disk to mounted filesystem:
# 1. Create the LV
lvcreate -L 50G -n lv_webapp vg_data
# 2. Create a filesystem on it
mkfs.ext4 /dev/vg_data/lv_webapp
# 3. Create mount point
mkdir /var/www
# 4. Mount it
mount /dev/vg_data/lv_webapp /var/www
# 5. Make it permanent in /etc/fstab
echo "/dev/vg_data/lv_webapp /var/www ext4 defaults 0 2" >> /etc/fstab
# 6. Verify
df -h /var/www
lvs - Quick Overview of Logical Volumes¶
What it does: Shows a summary of all Logical Volumes.
Why use it: Quick check of LV sizes, which VG they’re in, and their status.
Example:
lvs
Output:
LV VG Attr LSize Pool Origin Data%
lv_database vg_data -wi-ao---- 100.00g
lv_web vg_data -wi-ao---- 50.00g
lv_backup vg_data -wi-a----- 200.00g
What the attributes mean:
- w = writable
- i = inherited allocation policy
- a = active (usable)
- o = open (currently mounted)
lvdisplay - Detailed Logical Volume Information¶
What it does: Shows detailed information about Logical Volumes.
Why use it: Get full details including device paths, segments, and exact sizes.
Example:
# Show all LVs
lvdisplay
# Show specific LV
lvdisplay /dev/vg_data/lv_web
Output example:
--- Logical volume ---
LV Path /dev/vg_data/lv_web
LV Name lv_web
VG Name vg_data
LV UUID mno789-pqr012-...
LV Write Access read/write
LV Creation host, time server01, 2024-10-28 10:30:15
LV Status available
# open 1
LV Size 50.00 GiB
Current LE 12800
Segments 1
Allocation inherit
Read ahead sectors auto
Block device 253:0
lvextend - Increase Logical Volume Size¶
What it does: Makes a Logical Volume larger by allocating more space from the Volume Group.
Why use it: When you’re running out of space on a filesystem and need more room.
Examples:
# Add 10GB to an LV
lvextend -L +10G /dev/vg_data/lv_web
# Extend to a total of 100GB
lvextend -L 100G /dev/vg_data/lv_web
# Use all remaining free space in VG
lvextend -l +100%FREE /dev/vg_data/lv_web
# Extend AND resize the filesystem in one command (convenient!)
lvextend -L +10G -r /dev/vg_data/lv_web
Real-world scenario - Running out of space:
You’re getting warnings that /var/www is 90% full:
# Check current situation
df -h /var/www
# Shows: 45GB used out of 50GB (90% full)
lvs /dev/vg_data/lv_web
# Shows: 50GB LV
vgs vg_data
# Shows: 200GB free in VG
# Solution: Add 30GB more
lvextend -L +30G /dev/vg_data/lv_web
# Output: Size of logical volume vg_data/lv_web changed from 50.00 GiB to 80.00 GiB
# Resize the filesystem to use new space
resize2fs /dev/vg_data/lv_web
# Output: The filesystem is now 20971520 blocks long
# Verify
df -h /var/www
# Shows: 45GB used out of 80GB (56% full)
Important: After extending the LV, you must resize the filesystem:
- ext4/ext3/ext2: resize2fs /dev/vg_data/lv_name
- xfs: xfs_growfs /mount/point
- Or use -r flag with lvextend to do both automatically
lvreduce - Decrease Logical Volume Size¶
What it does: Makes a Logical Volume smaller, freeing space back to the Volume Group.
Why use it: When you over-allocated space and want to reclaim it for other uses.
WARNING: This is dangerous! Always backup data first!
Example:
# CRITICAL: Shrink filesystem FIRST, then LV
# If you shrink the LV first, you'll lose data!
# For ext4:
# Step 1: Unmount (required for shrinking)
umount /mnt/data
# Step 2: Check filesystem
e2fsck -f /dev/vg_data/lv_data
# Step 3: Shrink filesystem to 30GB
resize2fs /dev/vg_data/lv_data 30G
# Step 4: Shrink LV to match
lvreduce -L 30G /dev/vg_data/lv_data
# It will ask for confirmation - type 'y'
# Step 5: Remount
mount /dev/vg_data/lv_data /mnt/data
Real-world scenario: You allocated 100GB for /opt/app but only use 25GB:
# Check usage
df -h /opt/app
# Shows: 25GB used out of 100GB
# Back up data first! (Just in case)
tar czf /backup/app-backup.tar.gz /opt/app
# Unmount
umount /opt/app
# Check and repair filesystem
e2fsck -f /dev/vg_data/lv_app
# Shrink filesystem to 40GB (leaving room for growth)
resize2fs /dev/vg_data/lv_app 40G
# Shrink LV to match
lvreduce -L 40G /dev/vg_data/lv_app
# Remount
mount /dev/vg_data/lv_app /opt/app
# Verify
df -h /opt/app
# Now shows: 25GB used out of 40GB
# The freed 60GB is now available in vg_data for other uses
vgs vg_data
Note: XFS filesystems cannot be shrunk - only grown! Plan sizes carefully.
lvremove - Delete a Logical Volume¶
What it does: Completely removes a Logical Volume and frees its space back to the VG.
Why use it: Cleaning up unused volumes or removing test environments.
Example:
# Unmount first
umount /mnt/old
# Remove the LV
lvremove /dev/vg_data/lv_old
# Asks: "Do you really want to remove...?" type 'y'
# Or force removal without confirmation (dangerous!)
lvremove -f /dev/vg_data/lv_old
LVM Snapshots¶
What Are Snapshots?¶
A snapshot is a point-in-time copy of a Logical Volume. It doesn’t copy all the data immediately; instead, it uses copy-on-write technology: - When you create a snapshot, it initially uses very little space - As the original LV changes, the snapshot stores the old data - The snapshot shows how the LV looked at the moment you created it
Why Use Snapshots?¶
Perfect for: - Backing up a live database without stopping it - Testing changes safely (take snapshot, test, revert if needed) - Creating consistent backups of busy filesystems
Example Use Case: You need to backup a database that runs 24/7. You can’t stop it, but you need a consistent backup: 1. Take a snapshot (takes seconds) 2. The snapshot is a frozen point-in-time view 3. Back up from the snapshot (take hours if needed) 4. Original database keeps running and changing 5. Delete snapshot when backup complete
Creating Snapshots¶
# Create a 10GB snapshot of lv_database
lvcreate -L 10G -s -n lv_database_snap /dev/vg_data/lv_database
# The size (10GB) is for storing changes, not the whole database
# Size needed depends on how much changes during snapshot lifetime
Real-world scenario - Database backup:
# Your database LV is 100GB, actively being used
# Create snapshot (only needs space for changes during backup)
lvcreate -L 20G -s -n lv_db_backup /dev/vg_data/lv_database
# Output: Logical volume "lv_db_backup" created
# Mount the snapshot read-only
mkdir /mnt/snap
mount -o ro /dev/vg_data/lv_db_backup /mnt/snap
# Backup from snapshot (original database keeps running!)
tar czf /backup/database_$(date +%Y%m%d).tar.gz -C /mnt/snap .
# Cleanup
umount /mnt/snap
lvremove /dev/vg_data/lv_db_backup
Monitoring Snapshot Usage¶
What to watch: Snapshots need space to store changes. If they fill up, they become invalid!
# Check snapshot usage
lvs -a -o +snap_percent
# Output shows percentage used:
# LV VG ... Snap%
# lv_database_snap vg_data ... 15.23
If it reaches 100%, the snapshot becomes invalid and useless. Solution: make snapshot size larger.
Extending a Snapshot¶
# If snapshot is getting full, extend it
lvextend -L +5G /dev/vg_data/lv_database_snap
Reverting with Snapshots (Rollback)¶
What it does: Merges the snapshot back to the original, reverting all changes.
When to use: You tested something, it broke, and you want to undo everything.
Example:
# Before major system update:
# Take snapshot
lvcreate -L 20G -s -n lv_root_snap /dev/vg_system/lv_root
# Perform risky operation (install updates, etc.)
dnf update -y
# If something breaks, revert:
umount /
lvconvert --merge /dev/vg_system/lv_root_snap
# Reboot required to complete merge
reboot
# System comes back to pre-update state!
Warning: Merging destroys the snapshot and reverts the original LV. Make sure this is what you want!
Complete Real-World Examples¶
Example 1: Setting Up LVM from Scratch¶
Scenario: New server with three empty disks. Set up LVM for flexible storage.
# Step 1: Initialize physical disks
pvcreate /dev/sdb /dev/sdc /dev/sdd
# Output: Physical volume "/dev/sdb" successfully created.
# Physical volume "/dev/sdc" successfully created.
# Physical volume "/dev/sdd" successfully created.
# Step 2: Create volume group combining all disks
vgcreate vg_data /dev/sdb /dev/sdc /dev/sdd
# Output: Volume group "vg_data" successfully created
# Step 3: Check available space
vgs vg_data
# Shows total combined space (e.g., 1.5TB)
# Step 4: Create logical volumes for different purposes
lvcreate -L 200G -n lv_database vg_data
lvcreate -L 100G -n lv_webapp vg_data
lvcreate -L 50G -n lv_logs vg_data
lvcreate -l 100%FREE -n lv_backup vg_data
# Step 5: Create filesystems
mkfs.ext4 /dev/vg_data/lv_database
mkfs.xfs /dev/vg_data/lv_webapp
mkfs.ext4 /dev/vg_data/lv_logs
mkfs.ext4 /dev/vg_data/lv_backup
# Step 6: Create mount points
mkdir -p /data/database
mkdir -p /var/www
mkdir -p /var/log/apps
mkdir -p /backup
# Step 7: Mount filesystems
mount /dev/vg_data/lv_database /data/database
mount /dev/vg_data/lv_webapp /var/www
mount /dev/vg_data/lv_logs /var/log/apps
mount /dev/vg_data/lv_backup /backup
# Step 8: Make permanent in /etc/fstab
cat >> /etc/fstab << EOF
/dev/vg_data/lv_database /data/database ext4 defaults 0 2
/dev/vg_data/lv_webapp /var/www xfs defaults 0 2
/dev/vg_data/lv_logs /var/log/apps ext4 defaults 0 2
/dev/vg_data/lv_backup /backup ext4 defaults 0 2
EOF
# Step 9: Verify everything
df -h
lvs
Example 2: Expanding Storage When Running Out of Space¶
Scenario: /var/www is 95% full and you need more space immediately.
# Step 1: Check current situation
df -h /var/www
# Filesystem Size Used Avail Use% Mounted on
# /dev/vg_data/lv_webapp 50G 48G 2G 96% /var/www
# Step 2: Check if VG has free space
vgs vg_data
# VG #PV #LV #SN Attr VSize VFree
# vg_data 3 4 0 wz--n- 1.50t 500.00g
# Good! We have 500GB free
# Step 3: Extend the LV by 50GB
lvextend -L +50G /dev/vg_data/lv_webapp
# Output: Size of logical volume vg_data/lv_webapp changed from 50.00 GiB to 100.00 GiB
# Step 4: Resize the filesystem (xfs in this case)
xfs_growfs /var/www
# Output: data blocks changed from 13107200 to 26214400
# OR for ext4, use:
# resize2fs /dev/vg_data/lv_webapp
# Step 5: Verify
df -h /var/www
# Filesystem Size Used Avail Use% Mounted on
# /dev/vg_data/lv_webapp 100G 48G 52G 48% /var/www
# Problem solved! No downtime needed.
Example 3: Adding a New Disk to Existing Setup¶
Scenario: Server is running low on storage across all volumes. Add new 1TB disk.
# Step 1: Initialize new disk
pvcreate /dev/sde
# Output: Physical volume "/dev/sde" successfully created.
# Step 2: Add to existing volume group
vgextend vg_data /dev/sde
# Output: Volume group "vg_data" successfully extended
# Step 3: Verify new space available
vgs vg_data
# Now shows 1TB more space in VFree
# Step 4: Extend volumes that need space
# Database needs more space
lvextend -L +200G /dev/vg_data/lv_database
resize2fs /dev/vg_data/lv_database
# Backup needs more space
lvextend -L +300G /dev/vg_data/lv_backup
resize2fs /dev/vg_data/lv_backup
# Step 5: Verify
df -h
lvs vg_data
Example 4: Safe Database Maintenance with Snapshots¶
Scenario: Need to perform risky database migrations. Want ability to rollback.
# Step 1: Stop database (if possible) or at least sync
systemctl stop postgresql
# Step 2: Create snapshot (20GB for changes)
lvcreate -L 20G -s -n lv_db_premigration /dev/vg_data/lv_database
# Output: Logical volume "lv_db_premigration" created
# Step 3: Start database and perform migrations
systemctl start postgresql
./run-database-migration.sh
# Step 4a: If migration successful, remove snapshot
lvremove /dev/vg_data/lv_db_premigration
# Step 4b: If migration failed, rollback
systemctl stop postgresql
umount /data/database
lvconvert --merge /dev/vg_data/lv_db_premigration
# Merge will happen on next mount/reboot
mount /dev/vg_data/lv_database /data/database
systemctl start postgresql
# Database is now back to pre-migration state!
Example 5: Replacing a Failing Disk¶
Scenario: SMART errors on /dev/sdc. Need to replace without downtime.
# Step 1: Add new replacement disk
pvcreate /dev/sdf
vgextend vg_data /dev/sdf
# Step 2: Move data from failing disk to new disk
# This can take hours! System stays online.
pvmove /dev/sdc /dev/sdf
# Shows progress: /dev/sdc: Moved: 45.2%
# Step 3: After pvmove completes, remove old disk from VG
vgreduce vg_data /dev/sdc
# Step 4: Remove PV label
pvremove /dev/sdc
# Step 5: Physically remove /dev/sdc
# No data loss, no downtime!
Troubleshooting Common Issues¶
Issue 1: “Cannot create LV - insufficient space”¶
Problem: Trying to create LV but get error about insufficient space.
# Check VG free space
vgs vg_data
# If VFree is 0, you need to either:
# a) Add more disks
pvcreate /dev/sde
vgextend vg_data /dev/sde
# b) Remove or shrink other LVs to free space
lvremove /dev/vg_data/lv_unused
# or
lvreduce -L 50G /dev/vg_data/lv_oversized
Issue 2: “Device or resource busy” when removing LV¶
Problem: Can’t remove an LV because it’s in use.
# Find what's using it
lsof /dev/vg_data/lv_name
# or
fuser -m /mount/point
# Unmount it
umount /mount/point
# Try again
lvremove /dev/vg_data/lv_name
Issue 3: Snapshot became invalid¶
Problem: Snapshot shows “Snapshot status: INVALID”
Cause: Snapshot ran out of space to store changes.
# Check snapshot usage
lvs -a -o +snap_percent
# If near 100%, extend it quickly
lvextend -L +10G /dev/vg_data/lv_snap
# For future: create larger snapshots initially
Issue 4: Cannot activate LV¶
Problem: LV won’t activate after reboot.
# Scan for LVM volumes
pvscan
vgscan
lvscan
# Activate all
vgchange -ay
# Activate specific VG
vgchange -ay vg_data
Best Practices¶
1. Plan Before Creating - Think about future growth - Leave free space in VG (20-30%) for flexibility - Use logical naming (lv_database, not lv1)
2. Regular Monitoring
- Check space regularly: df -h and lvs
- Monitor VG free space: vgs
- Set up alerts at 80% full
3. Backup Before Changes - Always backup before shrinking - Take snapshots before risky operations - Document your LVM layout
4. Extent Size - Default 4MB is fine for most cases - Use larger (16MB+) for very large volumes (multiple TB)
5. Snapshot Management - Size snapshots appropriately (10-30% of original) - Don’t keep snapshots long-term (performance impact) - Monitor snapshot usage
6. Documentation - Keep diagrams of your LVM setup - Document which LVs contain what data - Note any special configurations
Quick Command Reference¶
# === Creating LVM from scratch ===
pvcreate /dev/sdb # Initialize disk
vgcreate vg_name /dev/sdb # Create volume group
lvcreate -L 50G -n lv_name vg_name # Create logical volume
mkfs.ext4 /dev/vg_name/lv_name # Format with filesystem
mount /dev/vg_name/lv_name /mnt # Mount it
# === Viewing status ===
pvs # List physical volumes
vgs # List volume groups
lvs # List logical volumes
# === Expanding storage ===
lvextend -L +10G /dev/vg/lv # Add 10GB to LV
resize2fs /dev/vg/lv # Grow ext4 filesystem
xfs_growfs /mount/point # Grow XFS filesystem
# === Snapshots ===
lvcreate -L 10G -s -n snap /dev/vg/lv # Create snapshot
lvremove /dev/vg/snap # Remove snapshot
lvconvert --merge /dev/vg/snap # Revert to snapshot
# === Adding storage ===
pvcreate /dev/sdc # Initialize new disk
vgextend vg_name /dev/sdc # Add to volume group
# === Removing storage ===
pvmove /dev/sdc # Move data off disk
vgreduce vg_name /dev/sdc # Remove from VG
pvremove /dev/sdc # Clean up