LVM basics

Logical Volume Management, or LVM for short, takes entire disks or individual partitions, and combines them together so the group can act as a single managable entity.

A few best practices to keep in mind when using LVM.

1. The Volume Group name should represent what kind of storage it exists on, such as vglocal00, vgsan00, vgdas00, vgiscsi00, vgraid00, etc.

2. The Logical Volume name should represent what the LV is being used for where possible, such as nfs00, data00, mysql00, var00, root00, etc. So the end result of a LV for MySQL running on SAN would be: /dev/vgsan00/mysql00

3. Never combine disks coming from different raids. In other words, don’t combine disks from a raid 1 and a raid 5 in the same Volume Group.

4. Never combine disks from different storage mediums, such as local storage and remote (SAN, DAS, iSCSI, etc).

5. Never combine non-partitioned and partitioned devices due to performance issues and general end user confusion.

6. To avoid end user confusion, a partition should be created on the new physical device as some tools may not be able to see that data already resides on the physical volumes when using tools like fdisk, parted, gdisk, etc.

Setup new disk

We are going to assume that your new disk is setup on /dev/sdb. First, determine if there is a disk label already set, and check for any existing information. You just want to avoid accidentally data loss:

[root@web01 ~]# parted /dev/sdb unit s print | grep Table
[root@web01 ~]# parted /dev/sdb unit s print

Set the disk label on the new disk to GPT:

[root@web01 ~]# parted -s -- /dev/sdb mklabel gpt

On the first partition only, start the partition on sector 2048 to follow generally accepted best practices to ensure partition alignment:

[root@web01 ~]# parted -s -a optimal -- /dev/sdb mkpart primary 2048s -1

Now confirm the starting sector of the partition is aligned for the disk:

[root@web01 ~]# parted -s -- /dev/sdb align-check optimal 1

Set the partition to use LVM:

[root@web01 ~]# parted /dev/sdb set 1 lvm on

Now review the disks newly created partition layout:

[root@web01 ~]# parted /dev/sdb unit s print

Setup the new disk with LVM:

[root@web01 ~]# pvcreate --metadatasize 250k /dev/sdb1

Create the volume group:

[root@web01 ~]# vgcreate vglocal00 /dev/sdb1

And now setup the logical volume to use all available disk space:

[root@web01 ~]# lvcreate -n data00 -l 100%FREE vglocal00

Format the logical volume with your filesystem:

[root@web01 ~]# mkfs.ext4 -v -m2 /dev/vglocal00/data00

And finally, mount the new volume:

[root@web01 ~]# mkdir /mnt/data
[root@web01 ~]# echo "/dev/vglocal00/data00   /mnt/data       ext4    defaults 0 0" >> /etc/fstab
[root@web01 ~]# mount -a
[root@web01 ~]# df -h

Shrink an existing Logical Volume

If you have to shrink an existing volume, there are a few steps that need to be taken. While its generally safe, you should always ensure that you have known good backups in place before proceeding.

Also note that you cannot shrink an existing volume while it is mounted. So this should be done during a scheduled maintenance window as you will need to stop any services that are using data from that volume.

First, unmount the logical volume:

[root@web01 ~]# umount /mnt/data

Run a file system check on the logical volume:

[root@web01 ~]# e2fsck -f /dev/vglocal00/data00

Now shrink the volume. In this example, we’re going to shrink it down to be 15G in size:

[root@web01 ~]# resize2fs /dev/vglocal00/data00 15G

Now reduce the file system to be 15G in size:

[root@web01 ~]# lvreduce -L 15G /dev/vglocal00/data00

Finally, mount the filesystem for normal use again:

[root@web01 ~]# mount -a

Shrink the root Logical Volume

As the / logical volume cannot be unmounted while the system is running, you need to boot the server off the distro’s cd, or boot in it a rescue environment if your running a Cloud server that supports this. While its generally safe to resize a volume, you should always ensure that you have known good backups in place before proceeding.

In this example, I’m running my server in VMware, so I can simply boot using a CentOS 6 installation cdrom. When the installation screen comes up, select:

Rescue installed system

When the screen asks if you would like the rescue environment to attempt to find your Linux installation and mount it under the directory /mnt/sysimage, select:

Skip

Now that your booted into the rescue enviroment, run the following commands so the system is aware of your LVM setup:

pvscan
vgscan
vgchange -a y
lvscan

In my case, my root logical volume is /dev/vg_local/lv_root. I want to shrink it from 60G down to 6G. I already confirmed that my data in the / partition does not exceed 6G.

First, run a file system check on the logical volume:

[root@web01 ~]# e2fsck -f /dev/vglocal00/lv_root

Now shrink the root volume. In this example, we’re going to shrink it down to be 6G in size:

[root@web01 ~]# resize2fs /dev/vglocal00/lv_root 6G

Then reduce the file system to be 6G in size:

[root@web01 ~]# lvreduce -L 6G /dev/vglocal00/lv_root

Finally, eject the CD, reboot the system, and check to ensure your / file system is now at 6G:

[root@web01 ~]# df -h /

Expand an existing Logical Volume

This operation can be done live with LVM2.

First confirm you have enough free space in the volume group by running:

[root@web01 ~]# vgs
[root@web01 ~]# vgdisplay vglocal00

Now lets expand the logical volume ‘data00’ from 15G to 25G total.

[root@web01 ~]# df -h
[root@web01 ~]# lvextend -L 25G /dev/vglocal00/data00
[root@web01 ~]# resize2fs /dev/vglocal00/data00
[root@web01 ~]# df -h

Add a new Logical Volume to an existing Volume Group

First confirm you have enough free space in the volume group by running:

[root@web01 ~]# vgs
[root@web01 ~]# vgdisplay vglocal00

Now create a new 5G logical volume called mysql00:

[root@web01 ~]# lvcreate -n mysql00 -L 5G vglocal00
[root@web01 ~]# mkfs.ext4 -v -m2 /dev/vglocal00/mysql00

Finally, mount the new logical volume:

[root@web01 ~]# mkdir /mnt/mysql-fs
[root@web01 ~]# echo "/dev/vglocal00/mysql00   /mnt/mysql-fs       ext4    defaults 0 0" >> /etc/fstab
[root@web01 ~]# mount -a
[root@web01 ~]# df -h

Remove a Logical Volume

First, unmount the volume:

[root@web01 ~]# umount /mnt/mysql-fs

Then remove the volume:

[root@web01 ~]# lvremove /dev/vglocal00/mysql00 
Do you really want to remove active logical volume mysql00? [y/n]: y
  Logical volume "mysql00" successfully removed