How to change Volumegroup PE size

Solution 1:

You can use pvmove to move around the allocated physical extents on the physical volume(s). You should make any logical volumes begin and end on extent boundaries (grow with lvresize). The underlying physical volume size(s) should probably also be an exact multiple of the new extent size too (fix that with pvresize).

As mentioned in a superuser answer to a related question, you could use something like this:

pvmove --alloc anywhere /dev/sdc1:103680-221247 /dev/sdc1:0-103679

to move the extents 103680-221247 to 0-103679 on the physical volume /dev/sdc1. You might need to move segments in steps. Use pvdisplay --maps /dev/sdc1 to show what extents are allocated on the physical volume /dev/sdc1.

Note that the extent size should not affect I/O performance (on LVM2), only the performance of the LVM tools themselves and the maximum sizes of the LVM components should be affected.

Solution 2:

You can only change the physical extent size of a volume group if no existing physical extents would need to be moved to complete the change. Otherwise you receive the error that you posted above.

The only other option is to recreate the volume group with the correct size.

To quote from the man page:

Once this value has been set, it is difficult to change it without recreating the volume group which would involve backing up and restoring data on any logical volumes. However, if no extents need moving for the new value to apply, it can be altered using vgchange -s.

Solution 3:

It is possible, but difficult. If you have the option, re-creating the VG is a much better option.
However, that wasn't an option for me, so here's how I changed my PE size from 4MB to 32MB.

  • First, shrink your PVs to a size that's divisible by your target PE size, i.e.:
    pvresize /dev/sdb --setphysicalvolumesize 3778436m
  • Next, resize all your LVs to a size divisible by your intended PE size using lvresize, i.e.: lvresize /dev/libvirtstorage/debian-8.7.1-amd64-netinst.iso --size 256
  • Next up is making sure the individual segments that make up each image are aligned to your new PE. This one is iffy, as you basically have to "defrag" your VG.
    I used the "lvm2defrag" tool for this (you don't need to run this on the machine itself, you can run this on any machine with PHP installed, it'll just generate the commands needed)
  • After this, if your total volume size, LV fragment size and free space are all divisible by your targeted PE size, you should be able to change the PE size:
    vgchange -s 32m the_vol

This entire process can be done without any downtime, the entire VG continues operating during all this.
One more pitfal to note: Beware of the difference between 32m and 32M, LVM commands interpret lower case m as MiB and upper case M as MB.