Kevin Sumner
Revision 1.0 -- 19 Jan 2011
Traditionally, filesystems are written directly to block devices or fixed partitions on those block devices. Many sites still employ this method of disk layout, but many times partitioned disks leave something to be desired.
For example, with traditional partitioned disks, if a filesystem gets full and needs to be extended, data must be shuffled around the disk using a tool like GParted, which generally requires at least a service outage, sometimes an entire machine outage. Similarly, when data needs to be moved to another block device for whatever reason (failing disk, extra space required, etc.), the same sort of outage must be taken so that the data remains in a stable state.
LVM works around these problems by employing a layered approach that allows for filesystems to be grown on-the-fly, new disks to be added, and data to be migrated to new disks, all without taking any downtime for the machine or the services it provides. Some LVM schemes (notably Solaris' ZFS and AIX's LVM) also incorporate RAID-like abilities to allow for further resilience; on Linux, LVM can accomplish redundancy by enabling mirroring on a logical volume. In general, it is better to accomplish redundancy at lower levles, such as through a hardware RAID controller or Linux's Multiple Device (md) software RAID driver. Linux md and hardware RAID devices are beyond the scope of this document.
Linux LVM uses three primary layers to accomplish it's goals:
A Physical Volume (PV) is effectively a specially formatted block device, be it a normal hard drive, a partition on a hard drive, a md abstraction, a SAN logical unit, or any number of other block-like devices such as a USB flash key or a file served as a block device through the Linux loop driver [see losetup(8)].
A Volume Group (VG) is a collection of PVs. This collection can be grown and shrunk on-demand and without affecting the data hosted from the volume group.
A Logical Volume (LV) is a container that resides on a VG. A logical volume provides block device on which a filesystem can be created. These can be grown and shrunk on-demand without taking downtime for the data it hosts.
While not technically part of LVM, it is worth taking a minute to talk about filesystems. A Filesystem (FS) hosted inside a LV are the same filesystems that are commonly used on Linux: ext3, ext4, xfs, jfs, etc. Ideally, a filesystem that the Linux kernel knows how to grow and shrink live like ext3 or ext4 should be used with LVM, but this isn't a requirement. As of this writing, the Linux kernel can manipulate the following filesystems online:
There are also Physical Extents (PE) and Logical Extents (LE). These are the "chunks" of data. For all day-to-day administrative purposes, the only specific knowledge required about PEs and LEs is that they both exist inside of a volume group and that all PEs/LEs inside of a single volume group have the same size.
Utilizing LVM in Linux only requires a small mount of added effortversus just a "plain 'ole" disk partition. First, you need to lay out partitions. You could technically use the disk device directly, but partitioning the drive into multiple slices buys you some flexibility in the long run, but makes logical volume mirrors difficult.
Once you've gotten your device all ready, you'll need to prepare the PV with pvcreate, collect the PVs into a VG with lvcreate, create LVs inside of the VG with vgcreate, then format the LVs as filesystems with mkfs (like normal).
To expand a volume group to a new disk or partition, simply prepare one or more new PVs on the new disk with pvcreate, then extend the VG with vgextend.
To move a VG to a new disk of equal or greater size, do all the same steps as an expansion to start. Then, move the data off of the PVs using pvmove. Once the PVs on the old disk are empty, you can then remove the old disk's PVs using vgreduce.
To expand a LV and the FS that it contains, first run lvresize on the LV to the size that you want. Once that is done, you will need to use the filesystem-specific tools to expand it to the new size of the LV; for ext2, ext3, and ext4, the resize2fs command does this. NOTE: You may need to unmount your filesystem before expanding it -- check your filesystem's documentation before trying any online resize.
To shrink a FS and LV it is in, you must first shrink the FS to the size that you want using the tools appropriate for your filesystem. Then, you can shrink the LV to fit the FS with the lvresize tool. NOTE: You may need to unmount your filesystem before shrinking it -- check your filesystem's documentation before trying any online resize.
For the examples in this section, I'm using a 4GB disk inside of a KVM virtual machine called '/dev/vdb'. There is nothing special about this disk, and it could just as easily be a 2TB disk on a real physical machine.
For most real block devices, you'll want to just want to make it one big partition. This makes it so that you can be certain that a mirrored LV won't be mirrored onto two PVs that reside on the same disk. In the case that you're installing on a desktop or a laptop, it can be prudent to use multiple PVs as this will give you the ability to shrink the VG later and reuse the now unused partitions to, say, dual boot Windows.
root@example.org# parted /dev/vdb GNU Parted 2.3 Using /dev/vdb Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) mklabel gpt Warning: The existing disk label on /dev/vdb will be destroyed and all data on this disk will be lost. Do you want to continue? Yes/No? yes (parted) unit % (parted) mkpart lvm 0% 25% (parted) mkpart lvm 25% 50% (parted) mkpart lvm 50% 75% (parted) mkpart lvm 75% 100% (parted) print Model: Virtio Block Device (virtblk) Disk /dev/vdb: 100% Sector size (logical/physical): 512B/512B Partition Table: gpt Number Start End Size File system Name Flags 1 0.02% 25.0% 25.0% lvm 2 25.0% 50.0% 25.0% lvm 3 50.0% 75.0% 25.0% lvm 4 75.0% 100% 25.0% lvm (parted) quit Information: You may need to update /etc/fstab. root@example.org#
root@example.org# aptitude install lvm2
[... snip ...]
root@example.org#
root@example.org# pvcreate /dev/vdb1 /dev/vdb2 /dev/vdb3 /dev/vdb4 Physical volume "/dev/vdb1" successfully created Physical volume "/dev/vdb2" successfully created Physical volume "/dev/vdb3" successfully created Physical volume "/dev/vdb4" successfully created root@example.org#
root@example.org# vgcreate datavg /dev/vdb1 /dev/vdb2 /dev/vdb3 /dev/vdb4 Volume group "datavg" successfully created root@example.org#
root@example.org# lvcreate -L 1GB -n packageslv datavg Logical volume "packageslv" created root@example.org#
root@example.org# mkfs.ext4 -L packagesfs /dev/mapper/datavg-packageslv
mke2fs 1.41.12 (17-May-2010)
Filesystem label=packagesfs
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
65536 inodes, 262144 blocks
13107 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=268435456
8 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 24 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
root@example.org#
root@example.org# mount -v /dev/mapper/datavg-packageslv /srv/packages
mount: you didn't specify a filesystem type for /dev/mapper/datavg-packageslv
I will try type ext4
/dev/mapper/datavg-packageslv on /srv/packages type ext4 (rw)
root@example.org#
Ok, it's now six months down the road, and we've decided that 1GB isn't big enough. Now we want to go resize the LV packageslv to 2GB. Since ext4 supports online resizing, this will be easy!
root@example.org# lvresize -L 2GB /dev/mapper/datavg-packageslv Extending logical volume packageslv to 2.00 GiB Logical volume packageslv successfully resized root@example.org#
root@example.org# resize2fs /dev/mapper/datavg-packageslv resize2fs 1.41.12 (17-May-2010) Filesystem at /dev/mapper/datavg-packageslv is mounted on /srv/packages; on-line resizing required old desc_blocks = 1, new_desc_blocks = 1 Performing an on-line resize of /dev/mapper/datavg-packageslv to 524288 (4k) blocks. The filesystem on /dev/mapper/datavg-packageslv is now 524288 blocks long. root@example.org#
What? Caveats? There are none!... Well, ok, no, that's not quite true.
When using Linux LVM, most other operating systems won't be able to use the volume groups. There is a chance that some BSD systems and, oddly enough, AIX might be able to read them. However, you should never expect that anything other than a modern Linux system will be able to read your Linux volume groups.
LVM does induce a minor amount of processing overhead, reportedly producing a <1% performance hit. Using LVM also incurs a minor amount of data usage on the disk; however, with disk sizes what they are, this is minimal, and usually irrelevant. In general, the administrative flexibility it provides is well worth these cost.
I drew heavily on the LVM HOWTO over at TLDP when I was learning LVM, and you'll probably find it useful as well.