LVM (Logical Volume Manager): flexible disk management with Physical Volumes โ Volume Groups โ Logical Volumes. Supports online resize, snapshots, and spanning multiple disks.
LVM concepts
Three-layer model
| Layer | Command prefix | Description |
|---|---|---|
| PV โ Physical Volume | pv* | A disk or partition initialised for LVM. Building block. |
| VG โ Volume Group | vg* | Named pool aggregating one or more PVs. Total storage. |
| LV โ Logical Volume | lv* | Virtual partition carved from the VG. Formatted and mounted. |
Key LVM terms
| Term | Description |
|---|---|
| PE โ Physical Extent | Smallest allocatable unit on a PV (default 4 MB) |
| LE โ Logical Extent | Matching unit on an LV (maps to PEs) |
| Thin provisioning | Allocate LVs larger than physical space (over-commit) |
| CoW snapshot | Point-in-time copy โ only changed blocks are stored |
Setup: PV โ VG โ LV
Create and format
| Command | Description |
|---|---|
| pvcreate /dev/sdb /dev/sdc | Initialise disks as Physical Volumes |
| vgcreate data-vg /dev/sdb /dev/sdc | Create Volume Group spanning both PVs |
| lvcreate -L 50G -n web-lv data-vg | Create 50 GB Logical Volume |
| lvcreate -l 100%FREE -n data-lv data-vg | Use all free space in the VG |
| lvcreate -l 80%VG -n data-lv data-vg | Use 80% of total VG capacity |
| mkfs.ext4 /dev/data-vg/web-lv | Format with ext4 |
| mkfs.xfs /dev/data-vg/web-lv | Format with XFS |
| mount /dev/data-vg/web-lv /var/www | Mount the Logical Volume |
Typical fstab entry using device mapper path:
/dev/data-vg/web-lv /var/www ext4 defaults,noatime 0 2
Inspecting LVM
pv* / vg* / lv* display commands
| Command | Description |
|---|---|
| pvs | One-line summary of all PVs |
| pvdisplay /dev/sdb | Detailed PV info (PE size, total/free PEs) |
| pvscan | Scan for PVs on all block devices |
| vgs | One-line summary of all VGs |
| vgdisplay data-vg | Detailed VG info (free space, PE count) |
| lvs | One-line summary of all LVs |
| lvdisplay /dev/data-vg/web-lv | Detailed LV info (size, path, type) |
| lsblk | Block device tree โ shows LVM hierarchy |
| dmsetup ls | Device mapper mappings (underlying LVM) |
Extending & resizing
Grow LV and filesystem
| Command | Description |
|---|---|
| vgextend data-vg /dev/sdd | Add a new disk to the Volume Group |
| lvextend -L +20G /dev/data-vg/web-lv | Grow LV by 20 GB |
| lvextend -L 100G /dev/data-vg/web-lv | Set LV to exactly 100 GB |
| lvextend -l +100%FREE /dev/data-vg/web-lv | Use all remaining free space in VG |
| lvextend -r -L +20G /dev/data-vg/web-lv | Extend LV and resize filesystem in one step (-r flag) |
| resize2fs /dev/data-vg/web-lv | Resize ext4 to fill LV (online, no unmount needed) |
| xfs_growfs /var/www | Resize XFS to fill LV (must be mounted, use mount point) |
| btrfs filesystem resize max /mnt | Resize Btrfs to fill LV (online) |
Shrink LV (ext4 only โ XFS cannot shrink)
| Command | Description |
|---|---|
| umount /var/www | Step 1: unmount |
| e2fsck -f /dev/data-vg/web-lv | Step 2: force check |
| resize2fs /dev/data-vg/web-lv 30G | Step 3: shrink filesystem to 30 GB |
| lvreduce -L 30G /dev/data-vg/web-lv | Step 4: shrink LV to match |
| mount /dev/data-vg/web-lv /var/www | Step 5: remount |
Shrink order matters: always shrink filesystem first, then LV. Doing it in reverse destroys the filesystem.
Snapshots
LVM snapshots
| Command | Description |
|---|---|
| lvcreate -s -n snap-lv -L 5G /dev/data-vg/web-lv | Create snapshot (5 GB CoW buffer) |
| mount -o ro /dev/data-vg/snap-lv /mnt/snap | Mount snapshot read-only for backup |
| lvs -a | List all LVs including snapshots (snap% shows usage) |
| lvconvert --merge /dev/data-vg/snap-lv | Rollback origin to snapshot state |
| lvremove /dev/data-vg/snap-lv | Delete snapshot without rolling back |
Snapshot fills up when CoW buffer is exhausted โ it becomes invalid. Allocate at least 10โ20% of original volume size, or use thin provisioned snapshots for better flexibility.
Moving & removing
Move, rename, remove
| Command | Description |
|---|---|
| pvmove /dev/sdb | Migrate data from /dev/sdb to other PVs (online) |
| pvmove /dev/sdb /dev/sdd | Migrate to specific target PV |
| vgreduce data-vg /dev/sdb | Remove PV from VG (after pvmove) |
| lvrename data-vg web-lv app-lv | Rename a Logical Volume |
| vgrename data-vg prod-vg | Rename a Volume Group |
| lvremove /dev/data-vg/web-lv | Delete LV (unmount first) |
| vgremove data-vg | Delete VG (all LVs must be removed first) |
| pvremove /dev/sdb | Remove PV label (must be removed from VG first) |