Storage Virtualization
Logical Volume Manager (LVM)
Read aloud is unavailable in this browser.
The Storage Flexibility Revolution
Imagine you're a system administrator managing a database server that's rapidly running out of disk space. The database partition is full, but you have unused space on another partition—or perhaps you've just installed an additional physical disk. In the traditional partitioning model, your options are limited and disruptive: you might need to back up data, repartition the disk, restore data, or even reinstall the operating system. This scenario has plagued system administrators since the dawn of computing.
The Logical Volume Manager (LVM) emerges as an elegant solution to this fundamental problem. LVM introduces a virtualization layer between physical storage devices and the file systems that reside upon them, enabling unprecedented flexibility in storage management. With LVM, enlarging that database partition becomes a simple, online operation—no downtime, no data migration, no system reinstallation.
This page provides an exhaustive exploration of LVM architecture, its design philosophy, the problems it solves, and the fundamental concepts that enable its remarkable flexibility.
By the end of this page, you will understand the complete LVM architecture, including its three-layer abstraction model, the precise mechanisms by which physical extents map to logical extents, the role of device-mapper in the Linux kernel, and how LVM solves the fundamental limitations of traditional disk partitioning. You will gain the conceptual foundation necessary to design, deploy, and manage LVM configurations in production environments.
The Problem with Traditional Partitioning
To truly appreciate LVM's elegant design, we must first understand the limitations of traditional disk partitioning that motivated its creation. Traditional partitioning, exemplified by MS-DOS MBR and GPT partition tables, directly connects file systems to contiguous regions on physical disks.
The Fixed-Size Dilemma:
When you create a partition using traditional methods, you allocate a fixed, contiguous range of disk sectors to that partition. Once created, the partition's boundaries are essentially immutable. Consider the implications:
- Partition size is determined at creation time, requiring you to predict future storage needs—a notoriously difficult task
- Partitions cannot easily be resized without destructive operations or third-party tools
- Partitions cannot span multiple physical disks, limiting capacity to the size of a single device
- Unused space in one partition cannot be reclaimed by another without repartitioning
- Moving partitions requires copying gigabytes or terabytes of data
| Capability | Traditional Partitioning | LVM |
|---|---|---|
| Resize partition without data loss | Extremely limited or impossible | Fully supported, often online |
| Span multiple physical disks | Not supported | Fully supported |
| Add storage without repartitioning | Not supported | Fully supported |
| Move data between physical devices | Requires manual copying | pvmove command, transparent |
| Create point-in-time copies | Not supported | Snapshots supported |
| Over-provision storage | Not possible | Thin provisioning supported |
| Performance striping | RAID controller only | Built-in striping support |
The Contiguity Constraint:
Traditional partitions require contiguous disk sectors. This constraint creates fragmentation at the partition level—not within the file system, but in the allocation of partitions themselves. If you have three 100GB partitions and delete the middle one, you have 100GB of free space, but you cannot create a 150GB partition spanning that gap and additional space at the end.
The Single-Disk Limitation:
Perhaps most critically, traditional partitions are confined to a single physical disk. No matter how many disks you add to a system, a single partition cannot leverage that combined capacity. This limitation fundamentally constrains system design and forces administrators into complex workarounds involving symbolic links, mount points, and manual data distribution.
In enterprise environments, the inability to resize partitions online leads to costly scheduled downtime. A 2019 industry survey found that organizations without LVM or similar volume management spent an average of 12 additional hours per year on storage-related maintenance windows. For mission-critical systems requiring 99.99% uptime, this translates to SLA violations and substantial financial penalties.
LVM Architecture Overview
LVM implements a three-layer abstraction that decouples file systems from physical storage devices. This layered architecture is the key to LVM's flexibility and power. Understanding each layer and the relationships between them is essential for mastering storage virtualization.
The Three Fundamental Layers:
- Physical Volumes (PVs): The lowest layer, representing actual storage devices or partitions
- Volume Groups (VGs): The middle layer, pooling one or more physical volumes into a unified storage pool
- Logical Volumes (LVs): The topmost layer, providing block devices that file systems actually use
This architecture follows the classic computer science principle of adding a layer of indirection to solve complexity. By inserting volume groups between physical devices and logical volumes, LVM gains the freedom to map logical storage to physical storage in flexible, non-contiguous ways.
The Abstraction Benefit:
Consider what happens when a file system writes data to a logical volume. The application sees only a standard block device—it has no knowledge that LVM exists. The file system issues I/O requests to the logical volume, which LVM translates into I/O requests to the appropriate physical volume regions. This translation is transparent, automatic, and efficient.
The power of this abstraction becomes apparent when you need to:
- Expand a logical volume: Simply allocate more space from the volume group
- Add more storage: Add a new physical volume to the volume group
- Migrate data: Move physical extents between physical volumes without interrupting access
- Create snapshots: Capture a point-in-time copy without stopping the application
LVM exemplifies the separation of concerns principle. Physical storage management (adding/removing disks, handling hardware differences) is isolated at the PV layer. Capacity aggregation and allocation policy live at the VG layer. File system sizing and data organization exist at the LV layer. Each layer can evolve independently, and changes at one layer don't ripple through the entire stack.
Physical Volumes: The Foundation Layer
Physical Volumes (PVs) represent the interface between LVM and actual storage hardware. A PV can be created on any block device: a complete disk, a disk partition, a RAID array, or even a loopback device for testing. When you initialize a block device as a PV, LVM writes a special label and metadata area to establish LVM's ownership of that device.
Physical Volume Structure:
A physical volume contains several critical components:
- LVM Label: A 512-byte structure at the beginning of the device (within the first 4 sectors) containing a UUID, size information, and pointer to metadata areas
- Metadata Area(s): One or more regions storing the volume group configuration, including all PVs, LVs, and their mappings
- Physical Extents (PEs): The actual data storage area, divided into fixed-size blocks called extents
12345678910111213141516171819202122232425262728293031323334353637383940
Physical Volume Layout═══════════════════════════════════════════════════════════════════════ ┌──────────────────────────────────────────────────────────────────────┐│ LVM Label (Sector 1) ││ ┌─────────────────────────────────────────────────────────────────┐ ││ │ Magic Number: "LABELONE" │ ││ │ Sector Number: Location of this label │ ││ │ CRC: Checksum for data integrity │ ││ │ Offset: Pointer to PV Header │ ││ │ Type: "LVM2 001" │ ││ └─────────────────────────────────────────────────────────────────┘ │├──────────────────────────────────────────────────────────────────────┤│ PV Header ││ ┌─────────────────────────────────────────────────────────────────┐ ││ │ PV UUID: 32-character unique identifier │ ││ │ Device Size: Total size in bytes │ ││ │ Metadata Area Descriptors: Location and size of metadata │ ││ │ Data Area Descriptors: Location and size of data area │ ││ └─────────────────────────────────────────────────────────────────┘ │├──────────────────────────────────────────────────────────────────────┤│ Metadata Area (MDA) - Typically 1MB ││ ┌─────────────────────────────────────────────────────────────────┐ ││ │ VG Metadata (ASCII text format): │ ││ │ - Volume Group configuration │ ││ │ - Physical Volume list and UUIDs │ ││ │ - Logical Volume definitions │ ││ │ - Segment mappings (LE → PE) │ ││ │ - Creation timestamps, sequence numbers │ ││ └─────────────────────────────────────────────────────────────────┘ │├──────────────────────────────────────────────────────────────────────┤│ Data Area (Physical Extents) ││ ┌───────────────────────────────────────────────────────────────────┐││ │ PE 0 │ PE 1 │ PE 2 │ ... │ PE n-1 │ PE n │ │││ │ (4MB) │ (4MB) │ (4MB) │ │ (4MB) │ (4MB) │ │││ │ │ │ │ │ │ │ │││ │ Mapped │ Mapped │ Free │ ... │ Mapped │ Free │ │││ │ to LV1 │ to LV2 │ │ │ to LV1 │ │ │││ └───────────────────────────────────────────────────────────────────┘│└──────────────────────────────────────────────────────────────────────┘Physical Extents (PEs):
Physical extents are the fundamental units of allocation in LVM. When you create a volume group, you specify an extent size (default is 4MB in LVM2). Every physical volume is divided into extents of this size, and every allocation operation works in terms of whole extents.
The extent size represents a crucial trade-off:
- Smaller extents (e.g., 1MB) provide finer-grained allocation but increase metadata overhead and reduce maximum volume size
- Larger extents (e.g., 64MB) reduce metadata overhead but may waste space when logical volumes don't align to extent boundaries
Why 4MB Default?
The 4MB default balances several concerns:
- It's large enough to minimize metadata overhead (one extent entry per 4MB of storage)
- It's small enough to limit wasted space (at most 4MB - 1 byte per logical volume)
- It aligns with common RAID stripe sizes and SSD erase block sizes
- With 4MB extents, a volume group can manage up to 256TB per logical volume (64K extents × 4MB)
- •UUID Identification: Every PV has a globally unique identifier, enabling LVM to track devices even when device names change (e.g., /dev/sda → /dev/sdb after adding hardware)
- •Metadata Redundancy: By default, each PV stores a copy of the entire volume group metadata, providing automatic redundancy
- •Device Agnostic: PVs can be created on any block device—HDDs, SSDs, NVMe drives, RAID arrays, iSCSI LUNs, or multipath devices
- •Flexible Sizing: PVs can be of different sizes within the same volume group; LVM handles the heterogeneity
- •Online Operations: PVs can be added to or removed from volume groups without unmounting file systems
The Device-Mapper Subsystem
LVM2, the current implementation of LVM on Linux, relies on the device-mapper (dm) kernel subsystem to perform the actual I/O remapping. Understanding device-mapper is essential because it's the kernel-level mechanism that makes LVM possible—and device-mapper's capabilities extend far beyond LVM.
What is Device-Mapper?
Device-mapper is a generic framework in the Linux kernel for mapping one block device onto another. It works by creating virtual block devices (dm devices) and intercepting I/O requests to these devices, translating them according to a configurable mapping table, and forwarding them to underlying devices.
Device-mapper provides the foundation for:
- LVM: Logical volume mapping
- dm-crypt: Whole-disk encryption (used by LUKS)
- dm-raid: Software RAID implementation
- dm-cache: SSD caching for HDDs
- dm-thin: Thin provisioning
- dm-snapshot: Copy-on-write snapshots
12345678910111213141516171819202122232425262728293031323334353637
Device-Mapper I/O Path════════════════════════════════════════════════════════════════════════ User Space Kernel Space┌─────────────────┐ ┌────────────────────────────────────────────┐│ │ │ ││ Application │ │ Virtual File System (VFS) ││ (read/write) │ │ │ ││ │ │ │ ▼ ││ ▼ │ │ File System (ext4, xfs) ││ /dev/vg/lv │ │ │ ││ │ │ ▼ ││ │ │ Block Layer ││ ═══════════════│═══════│══════════════│═════════════════════════ ││ │ │ │ ││ lvm2 tools │ │ Device-Mapper Core ││ (userspace) │ ───── │ ┌─────────┴─────────┐ ││ │ ioctl │ │ DM Target Driver │ ││ - lvcreate │ │ │ (dm-linear) │ ││ - lvextend │ │ └─────────┬─────────┘ ││ - lvremove │ │ │ ││ │ │ Mapping Table ││ │ │ ┌────────────────────────────────────┐ ││ │ │ │ Start Length Target Params │ ││ │ │ │ 0 102400 linear 8:1 0 │ ││ │ │ │ 102400 51200 linear 8:17 0 │ ││ │ │ └────────────────────────────────────┘ ││ │ │ │ ││ │ │ Block I/O forwarded to underlying ││ │ │ devices (/dev/sda1, /dev/sdb1) ││ │ │ │ │└─────────────────┘ │ ▼ │ │ SCSI/NVMe/SATA Drivers │ │ │ │ │ ▼ │ │ Physical Storage Hardware │ └────────────────────────────────────────────┘The Mapping Table:
The heart of device-mapper is the mapping table. Each entry in the table describes how a range of sectors in the virtual device maps to sectors in underlying devices. For a simple linear mapping:
start_sector num_sectors target_type target_args
0 204800 linear /dev/sda1 0
204800 102400 linear /dev/sdb1 0
This table creates a virtual device where:
- Sectors 0-204799 map to sectors 0-204799 of /dev/sda1
- Sectors 204800-307199 map to sectors 0-102399 of /dev/sdb1
Target Types:
Device-mapper supports multiple target types:
| Target | Description | Use Case |
|---|---|---|
| linear | Simple 1:1 mapping with offset | LVM linear volumes |
| striped | Distributes I/O across multiple devices | LVM striped volumes |
| mirror | Mirrors data to multiple devices | LVM mirrored volumes |
| snapshot | Copy-on-write snapshots | LVM snapshots |
| snapshot-origin | Original volume for snapshot | Source of LVM snapshot |
| thin | Thin provisioning | LVM thin volumes |
| raid | Software RAID levels 1/4/5/6/10 | dm-raid, LVM RAID |
| crypt | Transparent encryption | LUKS, dm-crypt |
| cache | SSD caching for slower devices | lvmcache |
LVM userspace tools (lvcreate, lvextend, etc.) are essentially sophisticated configuration managers for device-mapper. When you run 'lvcreate -L 10G -n myvolume myvg', the LVM tools calculate the mapping from logical extents to physical extents, convert this to a device-mapper table, and use ioctl calls to configure the dm target. The kernel does all actual I/O—LVM tools just set up the configuration.
Extent Mapping Mechanics
The core of LVM operation is the mapping between Logical Extents (LEs) in logical volumes and Physical Extents (PEs) in physical volumes. Understanding this mapping mechanism illuminates how LVM achieves its flexibility.
Allocation Policies:
When you create or extend a logical volume, LVM must decide which physical extents to allocate. LVM supports several allocation policies:
- Contiguous: All LEs must map to physically contiguous PEs on a single PV
- Cling: New extents should be on the same PV as existing ones if possible
- Normal (default): Allocate from any available PE, preferring fewer PVs
- Anywhere: Use any available PE, even from different PVs (enables striping)
These policies allow administrators to balance between:
- Contiguity for performance: Sequential I/O benefits from physically contiguous allocation
- Flexibility for growth: Non-contiguous allocation enables maximum space utilization
- Isolation for reliability: Distributing across PVs can improve fault tolerance
Segment-Based Mapping:
LVM doesn't store a separate mapping entry for every single extent. Instead, it uses segments—contiguous ranges of logical extents that map to contiguous ranges of physical extents on a single PV. This compression dramatically reduces metadata size.
For example, if LEs 0-999 all map to PEs 0-999 on /dev/sda1, LVM stores this as a single segment:
Segment 0: LE 0-999 → /dev/sda1 PE 0-999 (linear, 1000 extents)
Rather than 1000 individual mappings. When the logical volume is extended non-contiguously, a new segment is created:
Segment 0: LE 0-999 → /dev/sda1 PE 0-999 (linear, 1000 extents)
Segment 1: LE 1000-1499 → /dev/sdb1 PE 0-499 (linear, 500 extents)
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
# Actual LVM2 metadata format (simplified)# Location: stored in metadata area of each PV vg_main { id = "aB1CdE-2fGh-3iJk-4LmN-5oPq-6RsT-7UvWx" seqno = 42 format = "lvm2" status = ["RESIZEABLE", "READ", "WRITE"] extent_size = 8192 # 4MB in 512-byte sectors max_lv = 0 # unlimited max_pv = 0 # unlimited physical_volumes { pv0 { id = "xY9ZaB-8cDe-7fGh-6iJk-5LmN-4oPq-3RsT" device = "/dev/sda2" status = ["ALLOCATABLE"] pe_start = 2048 # First PE starts after metadata pe_count = 25599 # Total PEs on this PV (100GB) } pv1 { id = "uV8WxY-7zAb-6cDe-5fGh-4iJk-3LmN-2oPq" device = "/dev/sdb1" status = ["ALLOCATABLE"] pe_start = 2048 pe_count = 25599 # Total PEs on this PV (100GB) } } logical_volumes { lv_root { id = "rS1TuV-2wXy-3zAb-4cDe-5fGh-6iJk-7LmN" status = ["READ", "WRITE", "VISIBLE"] segment_count = 1 segment1 { start_extent = 0 extent_count = 5120 # 20GB type = "striped" stripe_count = 2 stripe_size = 128 # 64KB stripes stripes = [ "pv0", 0 # First stripe: PV0, PE 0 "pv1", 0 # Second stripe: PV1, PE 0 ] } } lv_data { id = "mN2oPq-3rSt-4uVw-5xYz-6AbC-7dEf-8gHi" status = ["READ", "WRITE", "VISIBLE"] segment_count = 2 segment1 { start_extent = 0 extent_count = 12800 # 50GB type = "linear" stripes = [ "pv0", 5120 # Starts after root volume on PV0 ] } segment2 { start_extent = 12800 extent_count = 7680 # 30GB additional type = "linear" stripes = [ "pv1", 2560 # Different PV for this segment ] } } }}LVM metadata is typically cached in memory after the first read. During normal I/O operations, no metadata lookup is required—the kernel's device-mapper already has the mapping table loaded. Metadata is only read during LVM commands (lvs, lvextend, etc.) or system boot. This design means LVM adds negligible overhead to steady-state I/O performance.
LVM Operations and Commands
LVM provides a comprehensive suite of commands for managing physical volumes, volume groups, and logical volumes. Understanding these commands and their underlying operations is essential for effective storage management.
Command Naming Convention:
LVM commands follow a consistent naming pattern:
- pv* commands: Physical volume operations (pvcreate, pvdisplay, pvremove, pvmove)
- vg* commands: Volume group operations (vgcreate, vgdisplay, vgextend, vgreduce)
- lv* commands: Logical volume operations (lvcreate, lvdisplay, lvextend, lvremove)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
#!/bin/bash# Complete LVM Setup Example# This script demonstrates creating a full LVM configuration # Step 1: Initialize physical volumes# Wipes existing signatures and writes LVM labelpvcreate /dev/sdb /dev/sdc # Verify PV creationpvdisplay /dev/sdb# Output shows:# PV Name: /dev/sdb# VG Name: (not yet assigned)# PV Size: 100.00 GiB# Allocatable: NO# PE Size: 0 (not assigned to VG yet)# Total PE: 0# Free PE: 0 # Step 2: Create a volume group containing both PVs# -s 8M sets extent size to 8MB (default is 4MB)vgcreate -s 8M vg_storage /dev/sdb /dev/sdc # Verify VG creationvgdisplay vg_storage# Output shows:# VG Name: vg_storage# VG Size: 199.99 GiB# PE Size: 8.00 MiB# Total PE: 25598# Alloc PE: 0# Free PE: 25598 # Step 3: Create logical volumes# Create a 50GB linear volume for databaseslvcreate -L 50G -n lv_database vg_storage # Create a 100GB volume using all space on sdb preferentiallylvcreate -L 100G -n lv_files vg_storage /dev/sdb # Create a striped volume for high-performance I/O# -i 2 = stripe across 2 PVs, -I 64K = 64KB stripe sizelvcreate -L 40G -n lv_fast -i 2 -I 64K vg_storage # Use remaining free space (-l 100%FREE means all free extents)lvcreate -l 100%FREE -n lv_backup vg_storage # Step 4: Create file systems on logical volumesmkfs.xfs /dev/vg_storage/lv_databasemkfs.ext4 /dev/vg_storage/lv_filesmkfs.xfs /dev/vg_storage/lv_fastmkfs.ext4 /dev/vg_storage/lv_backup # Step 5: Mount the volumesmkdir -p /mnt/{database,files,fast,backup}mount /dev/vg_storage/lv_database /mnt/databasemount /dev/vg_storage/lv_files /mnt/filesmount /dev/vg_storage/lv_fast /mnt/fastmount /dev/vg_storage/lv_backup /mnt/backup # Step 6: Add to fstab for persistence (using UUID)blkid /dev/vg_storage/lv_database >> /etc/fstab# Then edit fstab to add mount optionsExtending a logical volume does NOT automatically extend the file system residing on it. After lvextend, you MUST run the appropriate file system resize tool (xfs_growfs for XFS, resize2fs for ext4, etc.) or use 'lvextend -r' for automatic resizing. Forgetting this step is a common mistake that leaves the added space unused.
LVM Benefits and Trade-offs
LVM provides substantial benefits for storage management, but it's not without costs. A thorough understanding of both sides enables informed architectural decisions.
Key Benefits:
- •Dynamic Resizing: Grow or shrink logical volumes online without unmounting file systems (shrinking requires ext4 or other shrink-capable file systems)
- •Spanning Multiple Disks: A single logical volume can span multiple physical devices, breaking the single-disk capacity barrier
- •Online Data Migration: Use pvmove to relocate data between physical volumes without downtime—essential for replacing aging hardware
- •Snapshots: Create instant, space-efficient point-in-time copies for backups or testing (covered in detail on Page 4)
- •Thin Provisioning: Over-commit storage and allocate actual blocks on demand (covered in detail on Page 5)
- •Striping: Distribute I/O across multiple disks for improved throughput without hardware RAID
- •Consistent Naming: Logical volume paths (/dev/vg_name/lv_name) remain stable regardless of physical device order changes
- •Metadata Redundancy: VG metadata stored on every PV provides automatic resilience to single-disk metadata corruption
- •Additional Complexity: LVM adds a management layer that requires understanding and maintenance
- •Boot Complications: Root volumes on LVM require initramfs/initrd support; not all bootloaders handle LVM gracefully
- •Recovery Complexity: Recovering data from LVM volumes requires LVM-aware tools; accidental metadata corruption can be catastrophic
- •Slight Performance Overhead: Device-mapper adds a small latency per I/O (typically <1μs), negligible in most scenarios
- •No Cross-System Portability: Moving LVM volumes between different Linux systems requires metadata export/import
- •Database Servers: Frequently require storage expansion as data grows
- •Virtual Machine Hosts: Thin provisioning maximizes storage efficiency
- •Backup Infrastructure: Snapshots enable consistent backups without downtime
- •Cloud/Enterprise: Standard practice in RHEL, SUSE, and enterprise Linux deployments
- •SAN/NAS Integration: LVM works seamlessly with iSCSI and multipath storage
When designing LVM layouts, intentionally leave 10-20% of VG capacity unallocated. This free space enables snapshot creation, provides buffer for emergency growth, and facilitates pvmove operations during hardware upgrades. The most common LVM mistake is allocating 100% of space initially, then struggling when snapshots are needed.
KEEP LEARNING
There’s more to understand.
You’re reading the introduction. Create a free account to read the complete lesson, save notes and keep track of your progress.