LVM (Logical Volume Manager) allows you to take a portion of a block level device and use it as a repository for other block level devices. The most common example of a “block level device” is a hard drive, but it can also include a RAID array, a file, anything that you would normally access as you access the standard hard drive in your home computer. USB thumb drives, etc…
Basically, you set aside a block of storage and let it be controlled by LVM instead of the normal hard drive access. The block of storage can be the entire disk, a partition, or even an LVM block (yes, you can have LVM inside of LVM, and it is quite useful at times).
In the following example, we'll take a RAID set (named md0) and use the entire device as an LVM pv “Physical Volume”.
At this point, you can create a vg (Volume Group) using the pv. We'll call it “vg0”.
vgcreate vg0 /dev/md0
Now, you have a volume group “vg0” which has all of the storage available on the physical volume /dev/md0 (well, with a little overhead subtracted). Now, let's say you want to allocate 10G of storage for some testing. We'll call it “testing”.
lvcreate -L 10G -n testing vg0
At this point, testing is an unformated, unpartitioned block level device (hard drive). So, you can do anything you would normally do with it.
fdisk /dev/vg0/testing mkfs.ext4 -m 0 -L testing /dev/vg0/testing
When using lvm2 in an area where you might have “disks” which have additional lvm2 setups, you will sometimes get Too Much Information. For this, you can use the filter in /etc/lvm/lvm.conf. Setting this allows you to determine what is checked for lvm2 partitions. The example below Adds anything beginning with /dev/md and Removes anything else.
filter=[ "a|^/dev/md|", "r/.*/" ]
One example is a virtual server (Xen) which has Logical Volumes exported to running virtual. In some cases, those “drives” need to be set up as physical volumes for LVM2 inside the running virtual. But, typing 'vgs' or 'lvs' from the DOM0 will show all of them, which is not helpful.
Before you can reduce a partition, you must reduce the size of the underlying file system. I'm showing ext2/3/4 (tested on ext4) where you use the command resize2fs to do this. Obviously, if you do not care about the underlying file system, you can simply reduce the size and then format it as you like. So, for swap, simply umount the swap (swapoff), resize (lvreduce), recreate the swap (mkswap), then mount it (swapon)
For most file systems, you must unmount it first. If you're wanting to resize /, you'll need to boot from a CD to do this. Now, do your work.
# umount the file system first! Very important # # You MUST do an fsck on the file system e2fsck -f /dev/vg0/partition # resize the file system to the minimum size possible # The -p means "show me feedback" and the -M means "minimum" resize2fs -pM /dev/vg0/partition # now, reduce the actual partition size. # It MUST be larger than the file system size # the -L ###G tells it what the new size will be lvreduce -L 200G /dev/vg0/partition # grow the file system to the maximum of the partition resize2fs /dev/vg0/partition # check the file system again e2fsck -f /dev/vg0/partition
You can now remount the system.
This was based on an article at https://blog.shadypixel.com/how-to-shrink-an-lvm-volume-safely/
Sometimes you need more space in the logical volume you create. In this case, you must unmount the volume, grow the partition (LV) size, then grow the file system under it. This is the reverse of the above section.
We'll just use resize2fs to grow the file system, and lvextend to grow the partition
# umount the file system first! Very important # # You MUST do an fsck on the file system e2fsck -f /dev/vg0/partition # now, increase the actual partition size. # the -L ###G tells it what the new size will be lvextend -L 200G /dev/vg0/partition # grow the file system to the maximum of the partition resize2fs /dev/vg0/partition # check the file system again e2fsck -f /dev/vg0/partition
Note: lvextend allows you some shorthand to grow, based on the size of the Volume Group (VG) or the amount that is available. In this case, you use the lower case “L” for the size parameter, and use the below syntax for the size you created:
+###% followed by the key VG, LV, PVS, FREE or ORIGIN
Thus, if we wanted to extend the LV to 75% of the amount of free space on the VG, you would say:
lvextend -l +75%FREE /dev/vg0/partition
According to the documentation (man page) using lvextend without the -L or -l parameters is equivilent to:
lvextend /dev/vg0/partition /dev/device_name # same as lvextend -l +100%PVS /dev/vg0/partition
meaning it will try to take the entire size of the Physical Volume (PV) (/dev/devicename in this case). Obviously, this won't work if you already have an LV on it.
Problem: You are using LVM as an underlying structure. You want to make changes, but are not sure if the changes will cause problems. Solution is to create a snapshot of the LV, make your modifications, then revert if they cause problems.
In this, I will assume volume group vg0 has a logical volume virt has a size of 10G, and the changes will probably only be about 1 Gig. What that contains is irrelevant.
lvcreate -s -L 1G -n snap.virt /dev/vg0/virt
lvconvert --merge /dev/vg0/snap.virt
Problem: You are using LVM as an underlying file structure on a virtual, and you need more room. Solution is to simply grow the underlying container, then use pvresize to let lvm2 know about it.
lvresize -L 100G /dev/virtuals/my_domu-disk1
kpartx -lv /dev/virtuals/my_domu-disk
Common LVM Recipes Problem: You want to swap out an existing Physical Volume for a new one. Maybe a faster drive, or a better RAID set. To do this is a multi-step process, but it can be done with no downtime, though it will definitely put a strain on the drive subsystem, especially if you are moving from one software RAID set to another.
Following example assumes you have an existing Volume Group that consists of one hardware RAID partition (sdb1), and you want to move it to a software RAID partition (md0). I assume you know how to build the RAID array. To replace /dev/sdb1 with /dev/md0, you must first add md0 to the volume group, then move all data from the volume group to it, then remove sdb1 from the volume group. Note: the pvmove must move all allocated extents from sdb1 to md0 without having any downtime on the server. Thus, it takes a long time (hours, maybe days). However, if it dies in the middle, you can simply restart it with the same command.
# First, set a device to become a new physical volume. NOTE: This must be capable of holding all USED data in the current vg (ie, sum of all lv's) pvcreate /dev/md0 # Now, add it to the volume group (in this case, datalvm) vgextend /dev/datalvm /dev/md0 # And move all data from the old pv to the new one pvmove -v /dev/sdb1 # once done (and it can take hours), remove the old one from the volume group vgreduce datalvm /dev/sdb1 # and, if you want, remove the PV flag from the volume. pvremove /dev/sdb1