30
[root@localhost ~] vgdisplay
  --- Volume group ---
  VG Name               vg_root
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  7
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                3
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               297,59 GiB
  PE Size               4,00 MiB
  Total PE              76182
  Alloc PE / Size       59392 / 232,00 GiB
  Free  PE / Size       16790 / 65,59 GiB
  VG UUID               XXXXXXXXXX

PV:

[root@localhost ~] pvdisplay

  --- Physical volume ---
  PV Name               /dev/mapper/udisks-luks-uuid-ASDFASDF
  VG Name               vg_root
  PV Size               297,59 GiB / not usable 2,00 MiB
  Allocatable           yes 
  PE Size               4,00 MiB
  Total PE              76182
  Free PE               16790
  Allocated PE          59392
  PV UUID               YYYYYYYYYYY

So I have a VG with 65 GByte free space. But when I want to shrink this Volume Group about ~50 GByte:

pvresize -tv --setphysicalvolumesize 247G /dev/mapper/udisks-luks-uuid-ASDFASDF
  Test mode: Metadata will NOT be updated and volumes will not be (de)activated.
    Using physical volume(s) on command line
    Test mode: Skipping archiving of volume group.
    /dev/mapper/udisks-luks-uuid-ASDFASDF: Pretending size is 517996544 not 624087040 sectors.
    Resizing volume "/dev/mapper/udisks-luks-uuid-ASDFASDF" to 624087040 sectors.
    Resizing physical volume /dev/mapper/udisks-luks-uuid-ASDFASDF from 0 to 63231 extents.
  /dev/mapper/udisks-luks-uuid-ASDFASDF: cannot resize to 63231 extents as later ones are allocated.
  0 physical volume(s) resized / 1 physical volume(s) not resized
    Test mode: Wiping internal cache
    Wiping internal VG cache

So the error message is:

cannot resize to 63231 extents as later ones are allocated.

Q: How can I defrag the vg_root so I can remove the unneeded part of it?

p.s: I already found out that I only need to resize the PV to resize the VG, or are there any better commands to do the VG resize (ex.: what can I do if I would several VG's on a PV? ...)?

30

You can use pvmove to move those extents to the beginning of the device or another device:

sudo pvmove --alloc anywhere /dev/device:60000-76182

Then pvmove chooses where to move the extents to, or you can specify where to move them.

See pvs -v --segments /dev/device to see what extents are currently allocated.

  • For me issue was that it moved the PEs to other places. Had to specify destination e.g.: sudo pvmove --alloc anywhere /dev/sdX2:60000-76182 /dev/sdX2:3000-19182 – akostadinov Jan 14 '18 at 12:39
28

These are the steps required to resize an LVM or LVM2 partition:

sudo lvresize --verbose --resizefs -L -150G /dev/ubuntu/root

sudo pvresize --setphysicalvolumesize {any size here} /dev/sda5

The last command, pvresize, may yield the error

/dev/sda5: cannot resize to xxxxx extents as later ones are allocated.

You have to rearrange the unallocated space at the end of the LVM. That means after root and swap_1 partition. You can see the current arrangement of space with this command

pvs -v --segments /dev/sda5

pvs will show output like this

/dev/sda5 ubuntu lvm2 a-- 698.04g 150g 0 xxx+1 root 0 linear /dev/sda:0-xxx
/dev/sda5 ubuntu lvm2 a-- 698.04g 150g xxx+1 iii 0 free
/dev/sda5 ubuntu lvm2 a-- 698.04g 150g yyyy jjj swap 0 linear /dev/sda5:yyyy-end

Now use pvmove to remove external fragmentation:

sudo pvmove --alloc anywhere /dev/sda5:yyyy-end

Now let's see if moving the swap volume succeeded.

pvs -v --segments /dev/sda5

should show the new order of volumes:

/dev/sda5 ubuntu lvm2 a-- 698.04g 150g 0 xxx+1 root 0 linear /dev/sda:0-xxx
/dev/sda5 ubuntu lvm2 a-- 698.04g 150g xxx+1 iii swap 0 linear /dev/sda5:xxx+1-yyyy
/dev/sda5 ubuntu lvm2 a-- 698.04g 150g yyyy+1 end 0 free

After that, use GParted and resize the LVM to the maximum used area. The rest will be in unallocated space.

  • This is a pretty comprehensive answer - it would be helpful though if it included a step 0 for doing the filesystem resize, e.g. resize2fs. I don't think it needs to be in detail, but just having something there as a nudge to future viewers would be helpful – Justin Apr 21 '18 at 17:30
  • I had free space at the beginning, calling pvmove without a destination didn't move it to the beginning. What worked was pvmove --alloc anywhere /dev/sda5:yyyy-end 0-newend with "newend" calculated as end - yyyy. However I'm not sure if this works if the free space at the beginning is smaller than the range to be moved. Also I think there's a typo in your pvs outputs, I think you meant /dev/sda5:0-xxx instead of /dev/sda:0-xxx. – pcworld Jan 12 at 22:49
  • 1
    @Justin The --resizefs parameter of lvresize already takes care of resizing the underlying filesystem. – pcworld Jan 12 at 22:50
  • @pcworld just read the man page and seems you're right – Justin Jan 21 at 0:56
  • Excellent answer - but can you elaborate on the last step? I assume "resize the LVM" means "resize the physical volume?" Is there a way to do this without GParted, on the command line, for systems that do not have a GUI? – Kevin Keane Mar 19 at 17:22
1

This older post covers this sort of shrinking so you can use the new space for something else. You'll need to resize it to the data however before. This should cover that and other errors you get as well. As it's older, do read through first:

0

i use this method , not sure if it's the best but works for me

use it with caution and not SysAdmin

calculate the difference that cause the problem

324%4 = 0 no problem

but

324%32 = 10.125

that's the problem so it doesn't fit

i think it's called "get real number"

lvmdiskscan

to list involved partitions

then

pvresize /dev/*** --setphysicalvolumesize ***M

i have to add extra 4M to work , i think it's related to the old PE size

finally

vgchange -s 32M **
0

Previous answers helped me solve this problem, but I needed to automate it and so wrote pvshrink

# ./pvshrink /dev/vda2 
Moving 50 blocks from 714 to 664
  /dev/vda2: Moved: 4.00%
  /dev/vda2: Moved: 100.00%
50 of 50 (100.00%) done
Defragmentation complete.
Metadata size: 1048576 b
PE size: 4.0 MiB
Total size 1048576 b + 714 x 4194304 b = 2995781632 b (2.8 GiB)
    Wiping internal VG cache
    Wiping cache of LVM-capable devices
    Archiving volume group "fedora" metadata (seqno 15).
    /dev/vda2: Pretending size is 5851136 not 6287360 sectors.
    Resizing volume "/dev/vda2" to 5851136 sectors.
    Resizing physical volume /dev/vda2 from 0 to 714 extents.
    Updating physical volume "/dev/vda2"
    Creating volume group backup "/etc/lvm/backup/fedora" (seqno 16).
  Physical volume "/dev/vda2" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized

This invokes pvmove for you as many times as is necessary to defragment the PV, and then resizes it to its minimum possible size (which is slightly more than the used size due to metadata).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.