How can I shrink a Logical Volume, and re-allocate the freed space into a new partition on the same drive?

I have a drive, sda. It has two partitions:

sda1: /boot
sda2: LVM managed in Volume Group volgrp01

volgrp01 contains the following Logical Volumes:

lv_root (30 GB)
lv_swap (8 GB)
lv_scratch (430 GB)

What I want to do is reduce lv_scratch to 50 GB, and re-allocate that newly freed 380 GB into a new partition, sda3 (which I'll then add to another Volume Group).

I've attached an image of my desired BEFORE and AFTER. I'm right in the middle of learning about LVM, and while I can grasp the idea of resizing Logical Volumes within a Volume Group, I'm unsure of how one would re-allocate that space into a new partition.

I'm using RHEL6.

enter image description here


Solution 1:

Step 1: Make backups.

I know, most people skip this step, but you're making changes that can result in major data loss if you screw up, and you're taking guidance from a random stranger on the Internet. You are responsible for the safety of your data. I'm not.

Step 2: Shrink the filesystem in lv_scratch. If it's an ext2/3/4 filesystem, unmount it and use resize2fs; if it's something else, you'll need to look up documentation on resizing that type of filesystem.

For example:

resize2fs /dev/volgrp01/lv_scratch 50G

When it's done (assuming you're using resize2fs), it'll tell you the new size of the filesystem in bytes. Make a note of that number, because you can use it for a safety check in the next step.

Step 3: Shrink the logical volume using lvreduce.

  • If you want to be simple, use lvreduce --size 50G volgrp01/lv_scratch.
  • If you want to be extra cautious about not shrinking the LV to a size smaller than the filesystem it contains, check the physical extent size of your volume group using vgdisplay volgrp01, and calculate how many physical extents are needed to hold the byte size of your filesystem (using 1MB = 1048576 bytes). Then specify that number using the --extents option instead of the --size 50G.

Alternatively, you may be able to skip step 1 and instead use lvreduce's -r option to resize the filesystem automatically. That may be easier, but I don't have personal experience with it to know how reliable it is.

At this point I'd recommend running fsck -f on your /dev/volgrp01/vg_scratch just to make sure it's intact. If you get any errors about "access beyond end of device", it means you shrunk the LV too much and need to lvextend it before you proceed.

Step 4: Shrink the physical volume using pvresize.

pvresize --setphysicalvolumesize 88G /dev/sda2

You don't need an extra safety check here since pvresize will refuse to shrink the physical volume to a size that's too small for your existing logical volumes. But if the sizes of your other LVs aren't exact multiples of 1GB, the 88G might be too small and you may need use a different value.

Step 5: Shrink the sda2 partition using fdisk.

Run fdisk /dev/sda, and at its prompt, run p to look at your existing partitions. Note the starting sector number of your sda2 partition. Then delete the sda2 partition — this doesn't touch the actual data, just removes the record of where it starts and ends — and create a new sda2 with the same starting sector (this is vital) and a size of 88G. The partition's type code should be 8e, "Linux LVM".

If you want to be extra cautious — and I'd recommend you do, especially if you had to specify a different size to the pvresize earlier — check the PE size and Total PE of your physical volume using pvdisplay /dev/sda2 and multiply them together to find the size of the physical volume in bytes (again using 1MB = 1048576 bytes). Then subtract your new sda2 partition's starting sector number from its ending one, add 1 so that the last sector is counted, and multiply by your disk's sector size (which should be either 512 or 4096 bytes). Make sure the two results match.

Now create your new sda3 partition, save your changes, and quit fdisk. If you get a message about needing to reboot for the change to take effect, reboot.

Solution 2:

Not sure whether it will work - I've only increased pv. And any way DO NOT TRY IT ON VALUABLE DATA UNLESS YOUR HAVE READABLE BACKUP.

  1. Use FS-specific tool (if any) to resize FS on lv_scratch

  2. lvresize -L 50G /dev/volgrp01/lv_scratch

  3. pvresize --setphysicalvolumesize 88G /dev/sda2

  4. Resize your /dev/sda2 (not sure whether it is possible with parted/cfdisk etc, may be you'll need some other partition editor)

  5. Create new partition, make new pv, create volume group etc.

Double check all numbers when resizing as if you shrink you logical or physical volume more than FS you may end up with broken FS and lost data, usually it's better to left some unused space in case of confusion.