Snapshot Management with LVM and Btrfs
Snapshots represent one of the most powerful features of modern filesystems and volume managers, enabling point-in-time data capture with minimal overhead. Both LVM (Logical Volume Manager) and Btrfs provide snapshot capabilities, though with different implementations and characteristics. This guide covers configuring and managing snapshots using both technologies for backup, testing, and data recovery scenarios.
Table of Contents
- Snapshot Concepts and Use Cases
- LVM Snapshot Overview
- Creating LVM Snapshots
- LVM Thin Provisioning
- Btrfs Subvolumes and Snapshots
- Btrfs Snapshot Operations
- Snapper for Automated Management
- Snapshot Merging and Cleanup
- Conclusion
Snapshot Concepts and Use Cases
Snapshots capture filesystem state at specific moments without duplicating data immediately:
- Backup Points: Create recovery checkpoints before system changes
- Testing: Snapshot before updates and rollback if needed
- Development: Each developer gets isolated copy-on-write clone
- Migration: Capture consistent state during infrastructure transitions
- Archival: Preserve data state for compliance requirements
LVM uses copy-on-write (CoW) snapshots with dedicated space, while Btrfs employs efficient subvolume cloning with transparent CoW.
LVM Snapshot Overview
LVM Architecture Review
# Review LVM structure
pvdisplay # Show physical volumes
vgdisplay # Show volume groups
lvdisplay # Show logical volumes
# Check available space
df -h
# Monitor LVM status
lvm fullreport
Space Planning for Snapshots
# Determine required snapshot space
# Formula: (Expected change rate) × (Snapshot retention time)
# For database with 50% daily change rate, 7-day retention:
# 50% × 7 days = 350% of LV size minimum
# Check current LV usage
df -h /path/to/lv
du -sh /path/to/lv
# View LVM metadata
vgdisplay | grep -E "VG Name|VG Status|Total PE"
lvdisplay | grep -E "LV Name|LV Size|Allocated to snapshot"
# Calculate required space
# If LV is 100GB with 50GB usage: need 50-150GB for snapshots
Creating LVM Snapshots
Basic LVM Snapshot Creation
# Create snapshot of active LV
sudo lvcreate -L50G -s -n backup-snapshot /dev/vg0/data
# Parameters explained:
# -L50G: Snapshot size
# -s: Create snapshot
# -n: Snapshot name
# /dev/vg0/data: Source LV
# Verify snapshot creation
sudo lvs
# List snapshot details
sudo lvdisplay /dev/vg0/backup-snapshot
# Check snapshot usage
sudo lvs -o lv_name,size,data_percent /dev/vg0
# Monitor snapshot in real-time
sudo watch -n 1 'lvs -o lv_name,size,data_percent /dev/vg0'
Using Snapshots for Backup
# Create snapshot for backup
sudo lvcreate -L100G -s -n backup-snap /dev/vg0/database
# Mount snapshot read-only
sudo mkdir -p /mnt/backup
sudo mount -o ro /dev/vg0/backup-snap /mnt/backup
# Perform backup
sudo tar czf /backup/database-$(date +%Y%m%d).tar.gz /mnt/backup/
# Or using rsync
sudo rsync -av --delete /mnt/backup/ /backup/database-copy/
# Unmount after backup
sudo umount /mnt/backup
# Remove snapshot when done
sudo lvremove -f /dev/vg0/backup-snap
Snapshot for Testing Risky Changes
# Create snapshot before system update
sudo lvcreate -L80G -s -n pre-update-snap /dev/vg0/root
# Mount alternate snapshot mount for testing
sudo mkdir -p /mnt/test
sudo mount /dev/vg0/pre-update-snap /mnt/test
# Test application changes in isolated environment
# Without risk to production data
# Unmount and remove when testing complete
sudo umount /mnt/test
sudo lvremove -f /dev/vg0/pre-update-snap
Snapshot Rollback
# Merge snapshot back to original (lose current changes)
sudo lvconvert --merge /dev/vg0/backup-snap
# Filesystem must be unmounted
sudo umount /dev/vg0/data || true
# Merge will complete on next reboot or immediately
sudo lvs -o lv_name,snap_percent
# After merge completes
sudo mount /dev/vg0/data /
LVM Thin Provisioning
Thin provisioning enables efficient snapshot management with dynamic space allocation:
Setting Up Thin Pools
# Create thin pool for snapshots
sudo lvcreate -L200G -T /dev/vg0/thin-pool
# Create thin LV from pool
sudo lvcreate -V100G -T /dev/vg0/thin-pool -n thin-lv
# Format filesystem
sudo mkfs.ext4 /dev/vg0/thin-lv
# Mount thin volume
sudo mount /dev/vg0/thin-lv /data
# Verify thin pool
sudo lvs -o lv_name,pool_lv,size,data_percent
# Monitor thin pool usage
sudo watch -n 2 'lvs -o lv_name,pool_lv,size,data_percent /dev/vg0'
Thin Volume Snapshots
# Create snapshot of thin volume (uses pool space)
sudo lvcreate -k n -K n -s -n thin-snap /dev/vg0/thin-lv
# Snapshot parameters:
# -k n: Don't activate snapshot immediately
# -K n: No skip zero fill
# -s: Snapshot
# -n: Snapshot name
# Verify snapshot
sudo lvs -o lv_name,pool_lv,size /dev/vg0
# Mount snapshot (read-only recommended)
sudo mount -o ro /dev/vg0/thin-snap /mnt/snapshot
# Create multiple snapshots from same thin LV
sudo lvcreate -k n -s -n snap-$(date +%Y%m%d-%H%M%S) /dev/vg0/thin-lv
# List all snapshots
sudo lvs -s
Thin Pool Expansion
# Monitor thin pool exhaustion
sudo lvs -o lv_name,pool_lv,size,data_percent | grep thin-pool
# Extend thin pool when approaching capacity
sudo lvextend -L+100G /dev/vg0/thin-pool
# Verify expansion
sudo lvs /dev/vg0/thin-pool
# Extend underlying PV if needed
sudo pvextend /dev/sdc /dev/sdd
sudo vgextend /dev/vg0 /dev/sdd
Btrfs Subvolumes and Snapshots
Btrfs Filesystem Preparation
# Create Btrfs filesystem
sudo mkfs.btrfs -L data /dev/sda
# Mount filesystem
sudo mount /dev/sda /mnt/btrfs
# Create subvolumes (similar to LVM LVs)
sudo btrfs subvolume create /mnt/btrfs/home
sudo btrfs subvolume create /mnt/btrfs/www
sudo btrfs subvolume create /mnt/btrfs/database
# List subvolumes
sudo btrfs subvolume list /mnt/btrfs
# Get detailed subvolume info
sudo btrfs subvolume show /mnt/btrfs/home
# Filesystem status
sudo btrfs filesystem show /mnt/btrfs
Creating Btrfs Snapshots
# Create read-only snapshot
sudo btrfs subvolume snapshot -r /mnt/btrfs/database /mnt/btrfs/database-backup-$(date +%Y%m%d)
# Create read-write snapshot (for cloning)
sudo btrfs subvolume snapshot /mnt/btrfs/www /mnt/btrfs/www-test
# List snapshots
sudo btrfs subvolume list -s /mnt/btrfs
# Check snapshot info
sudo btrfs subvolume show /mnt/btrfs/database-backup-20240115
# Mount snapshot at different location
sudo mkdir -p /mnt/recovered
sudo mount -o subvol=database-backup-20240115 /dev/sda /mnt/recovered
# Take snapshot of snapshot (multi-level)
sudo btrfs subvolume snapshot -r /mnt/btrfs/database-backup-20240115 \
/mnt/btrfs/database-backup-20240115-archived
Btrfs Snapshot Operations
Snapshot Scheduling with Btrfs
# Create script for automated snapshots
cat > /usr/local/bin/btrfs-snapshot.sh <<'EOF'
#!/bin/bash
MOUNT_POINT="/mnt/btrfs"
SUBVOL="database"
DATE=$(date +%Y%m%d_%H%M%S)
# Create read-only snapshot
btrfs subvolume snapshot -r \
${MOUNT_POINT}/${SUBVOL} \
${MOUNT_POINT}/${SUBVOL}-backup-${DATE}
# Remove snapshots older than 7 days
find ${MOUNT_POINT} -maxdepth 1 -type d -name "${SUBVOL}-backup-*" -mtime +7 -exec btrfs subvolume delete {} \;
echo "Snapshot ${SUBVOL}-backup-${DATE} created successfully"
EOF
chmod +x /usr/local/bin/btrfs-snapshot.sh
# Schedule via cron
echo "0 1 * * * /usr/local/bin/btrfs-snapshot.sh" | sudo tee -a /etc/crontab
Btrfs Incremental Backups
# Create initial full snapshot
sudo btrfs subvolume snapshot -r /mnt/btrfs/data /mnt/btrfs/data-full-20240101
# Send snapshot to backup location
sudo btrfs send /mnt/btrfs/data-full-20240101 | sudo tee /backup/data-full-20240101.btrfs > /dev/null
# Create incremental snapshot
sudo btrfs subvolume snapshot -r /mnt/btrfs/data /mnt/btrfs/data-incr-20240102
# Send incremental (only changes)
sudo btrfs send -p /mnt/btrfs/data-full-20240101 /mnt/btrfs/data-incr-20240102 | \
sudo tee /backup/data-incr-20240102.btrfs > /dev/null
# Receive and restore snapshots
sudo btrfs receive -f /backup/data-full-20240101.btrfs /mnt/restore/
# Restore incremental
sudo btrfs receive -f /backup/data-incr-20240102.btrfs /mnt/restore/
Snapper for Automated Management
Installing and Configuring Snapper
# Install snapper (Ubuntu/Debian)
sudo apt-get install -y snapper snapper-gui
# Or CentOS/RHEL
sudo yum install -y snapper
# Initialize snapper for filesystem
sudo snapper -c root create-config /
# List configurations
sudo snapper list-configs
# View current configuration
sudo snapper -c root get-config
Snapper Configuration
# Edit snapper configuration
sudo nano /etc/snapper/configs/root
# Key settings:
# TIMELINE_CREATE=yes # Auto create periodic snapshots
# TIMELINE_CLEANUP=yes # Auto cleanup old snapshots
# NUMBER_LIMIT=50 # Keep 50 snapshots maximum
# ALLOW_USERS=user1,user2 # Allow users to list snapshots
# ALLOW_GROUPS=sudo # Allow group to create/restore
# Apply configuration
sudo systemctl restart snapper-timeline.timer
# Verify timer is active
systemctl status snapper-timeline.timer
Using Snapper
# List snapshots
sudo snapper -c root list
# Detailed snapshot info
sudo snapper -c root list -a
# Create manual snapshot
sudo snapper -c root create -d "Before system update"
# Create snapshot with cleanup policy
sudo snapper -c root create --cleanup-algorithm=number -d "Snapshot"
# View differences between snapshots
sudo snapper -c root diff 10..11
# Show files changed
sudo snapper -c root diff 10..0
# Restore file from snapshot
sudo snapper -c root restore 10 /etc/important-config.conf
# Rollback entire system to snapshot
sudo snapper -c root undochange 10..0
# Delete snapshots
sudo snapper -c root delete 10
Snapshot Merging and Cleanup
LVM Snapshot Cleanup
# Monitor snapshot usage
sudo lvs -o lv_name,size,data_percent,snap_percent
# Extend full snapshot
sudo lvextend -L+50G /dev/vg0/backup-snap
# Remove snapshot when done
sudo lvremove -f /dev/vg0/backup-snap
# Batch cleanup old snapshots
for snapshot in $(sudo lvs --noheadings -S "snap_percent>80" -o lv_name); do
echo "Snapshot $snapshot is >80% full, consider removing"
done
# Cleanup multiple snapshots
sudo lvremove -f /dev/vg0/snap-{1,2,3}
# View snapshot lifecycle
sudo lvs --noheadings -o lv_name,size,data_percent -S "pool_lv=thin-pool"
Btrfs Subvolume Cleanup
# Remove old snapshots
sudo btrfs subvolume delete /mnt/btrfs/database-backup-old
# Recursive deletion
sudo btrfs subvolume delete -c /mnt/btrfs/database-backup-20240101
# Find and remove snapshots by name pattern
find /mnt/btrfs -maxdepth 1 -name "*.backup-*" -exec btrfs subvolume delete {} \;
# Defragment Btrfs volume to recover space
sudo btrfs filesystem defragment -r -v /mnt/btrfs
# Balance filesystem space
sudo btrfs balance start /mnt/btrfs
sudo btrfs balance status /mnt/btrfs
# Cleanup orphaned space
sudo btrfs balance start -musage=5 -susage=5 /mnt/btrfs
Conclusion
Snapshots represent essential infrastructure capabilities for modern system management. LVM snapshots provide compatibility with traditional environments while Btrfs offers superior efficiency and advanced features. By implementing automated snapshot policies, maintaining adequate free space, and regularly testing recovery procedures, organizations establish resilient data protection strategies. Understanding both technologies enables informed decisions about filesystem selection and recovery architecture. Whether protecting databases, testing configurations, or maintaining compliance requirements, snapshot management delivers critical value for enterprise data center operations.


