LVM Basics: Extending a Logical Volume
"The database volume is at 95 percent, can you make it bigger?" is the storage request I get most. On LVM (the CentOS 7 default, optional on Ubuntu) it's a ten-minute job, no reboot, no unmount. On a bare partition it's miserable, which is most of the case for LVM.
Two situations come up: the volume group still has free space, or you have to add a disk first. Commands are the same on CentOS 7 and Ubuntu 16.04. Take a recent backup before you start. Growing is safe in practice, but storage is where mistakes are expensive, and I don't skip that.
Look at the layout first
LVM has three layers: physical volumes (disks or partitions), volume groups (pools made of physical volumes) and logical volumes (what you format and mount). Look at all three:
sudo pvs
sudo vgs
sudo lvs -o +devices
df -hT /var/lib/mysql
Typical output on a CentOS 7 VM:
VG #PV #LV #SN Attr VSize VFree
centos 1 3 0 wz--n- <49.51g 4.00g
LV VG Attr LSize Devices
data centos -wi-ao---- 20.00g /dev/sda2(2560)
root centos -wi-ao---- 20.00g /dev/sda2(0)
swap centos -wi-ao---- 2.00g /dev/sda2(7680)
The VFree column tells you whether you can skip the next section. Here there are 4 GB free in the group.
If VFree is zero, add a disk
If VFree is zero, attach a new disk through your hypervisor or cloud console, then find it. It appears without a reboot; if not, ask the kernel to rescan:
lsblk
echo "- - -" | sudo tee /sys/class/scsi_host/host0/scan
Suppose the new disk is /dev/sdb. Turn it into a physical volume and add it to the group. I use the whole disk rather than partitioning it; there is no advantage to a partition table here.
sudo pvcreate /dev/sdb
sudo vgextend centos /dev/sdb
sudo vgs
VFree now reflects the new disk. For a virtual disk that was grown in place rather than added, use pvresize /dev/sda2 after fixing the partition table with growpart from the cloud-utils-growpart package.
Extend the LV and the filesystem
lvextend can resize the filesystem in the same step with -r, which calls xfs_growfs or resize2fs for you. Grow by a fixed amount:
sudo lvextend -r -L +10G /dev/centos/data
Or take everything that is free in the group:
sudo lvextend -r -l +100%FREE /dev/centos/data
Note the difference between -L (size in bytes with a unit) and -l (size in extents or a percentage). Both XFS and ext4 grow while mounted.
If you prefer to do the filesystem step separately, or you are on a tool version without -r:
sudo lvextend -L +10G /dev/centos/data
sudo xfs_growfs /var/lib/mysql # XFS takes the mount point
sudo resize2fs /dev/centos/data # ext4 takes the device
Did it grow?
sudo lvs
df -hT /var/lib/mysql
The LSize in lvs and the Size column in df should both show the new size. On XFS, xfs_info /var/lib/mysql reports the block count in data = ... blocks=; multiply by the block size to cross-check. Nothing on the volume needs restarting; MySQL or whatever lives there just sees more free space.
Errors I've hit
Insufficient free space: 2560 extents needed, but only 1024 available. You asked for more than the group has. Checkvgs, use+100%FREE, or add a disk first.Filesystem /dev/mapper/centos-data has unsupported feature(s)orresize2fs: Bad magic number in super-block. You ranresize2fson an XFS volume. Usexfs_growfswith the mount point instead.blkid /dev/centos/datashows the actual filesystem type.Device /dev/sdb excluded by a filter.The disk carries an old partition table or filesystem signature. Confirm it really is the right, empty disk withlsblk -f, thensudo wipefs -a /dev/sdband retrypvcreate.xfs_growfs: /dev/centos/data is not a mounted XFS filesystem.xfs_growfswants the mount point, not the device node, on the version in CentOS 7.
Shrinking is a different story: XFS cannot shrink at all, and ext4 must be unmounted to do so. So I size logical volumes small and leave headroom in the volume group. Growing is cheap and online; shrinking is neither.