Move LVM Data Between Physical Volumes with pvmove

pvmove shifts allocated LVM extents from one physical volume to another while the logical volumes on top of them stay mounted and in use. The examples use pvmove from LVM2 2.03.16(2), supplied here by package lvm2 version 2.03.16-3ubuntu3.2. Allow 15 to 30 minutes for a small, lightly used move; large volumes take much longer and load the storage while data copies.

Warning: This changes live storage metadata. Confirm every device path before running the move. Do not use a whole-disk placeholder such as /dev/sdb unless it is genuinely the PV you intend to change.

1. Record the current layout

Start with read-only reports before you touch anything. Replace the example paths only once you know the real source and destination PVs.

$ sudo pvs -o pv_name,vg_name,pv_size,pv_free
$ sudo vgs -o vg_name,vg_size,vg_free
$ sudo lvs -o lv_name,vg_name,lv_size,devices

Save the output somewhere appropriate for your change record. The source PV is the device whose allocated extents will move. The destination needs enough free extents for the data selected, and both PVs must belong to the same volume group.

Checkpoint: write down the exact source PV, destination PV, volume group, and any LV that must be included or excluded. If the reports do not make those relationships clear, stop and investigate with sudo pvdisplay, sudo vgdisplay, and sudo lvdisplay.

2. Choose the narrowest move

These are examples, not commands to paste unchanged. Check the final device names with pvs immediately before starting. A move can affect mounted filesystems through their LVs, so only keep applications running if that workload is acceptable for your storage and backup plan.

3. Limit the physical extent range when needed

A PV argument can include an inclusive physical extent range. Useful when a particular region is being cleared, or you have a precise evacuation plan.

$ sudo pvmove /dev/OLD_PV:1000-1999 /dev/NEW_PV
$ sudo pvmove /dev/OLD_PV:1000+1000 /dev/NEW_PV

The first form names extents 1000 through 1999. The second starts at extent 1000 and moves 1000 extents. Extent numbering starts at zero. Do not infer a range from a filesystem's byte offset: PV extents and filesystem blocks are different layers.

To pick exact destination extents too, add a range to the destination:

$ sudo pvmove /dev/OLD_PV:1000-1999 /dev/NEW_PV:0-999

Both ranges must be large enough and suitable for the LV segments being moved. When source and destination ranges sit on the same disk, the documented command needs --alloc anywhere:

$ sudo pvmove --alloc anywhere /dev/OLD_PV:1000-1999 /dev/OLD_PV:0-999

Same-disk moves do not give you the physical failure isolation a separate disk does. Treat this as layout work, not a disk replacement.

4. Start and monitor the move

Run the selected command in a terminal where you can keep its output. --interval controls regular progress reporting:

$ sudo pvmove --interval 5 /dev/OLD_PV /dev/NEW_PV

A successful foreground command returns to the shell once the move completes; the exact progress text depends on your LVM configuration. Check the result with:

$ sudo pvs -o pv_name,vg_name,pv_size,pv_free
$ sudo lvs -o lv_name,vg_name,lv_size,devices

For a completely empty source PV, its free space should now match its size, subject to rounding and any extents you deliberately left behind. The LV device report should no longer show moved segments on that PV.

Warning: a zero exit status is not proof the intended PV was selected. Compare the before and after reports.

You can request background polling with --background, which returns before the operation completes:

$ sudo pvmove --background --interval 10 /dev/OLD_PV /dev/NEW_PV

Only use background mode when you have a separate way to monitor completion. If the shell disconnects, the move itself resumes from checkpoints, but an unattended command is easier to misread during an incident.

5. Resume or abort an interrupted move

Checkpoint: if the host crashed, the command was interrupted, or you lost the terminal, do not start a different layout change first. Resume pending work with no PV arguments:

$ sudo pvmove

The manpage describes a temporary pvmove LV and on-disk checkpoints. Running pvmove with no PV arguments tells LVM to continue an operation already in progress. Inspect the reports again once it finishes.

To abandon an operation instead:

$ sudo pvmove --abort

Warning: abort is a state-changing action. Without --atomic, segments already moved stay on the destination and the rest stay on the source; a later ordinary pvmove can finish the evacuation if the resulting layout is acceptable. If the original move used --atomic, an abort leaves all affected LVs on the source PV.

6. Use atomic mode when abort consistency matters

Add --atomic when you need all-or-nothing placement if the move gets aborted:

$ sudo pvmove --atomic /dev/OLD_PV /dev/NEW_PV

Atomic mode needs sufficient temporary allocation and can have different space and performance characteristics. It does not make a failing disk safe, and it does not undo a move that already completed successfully. Decide before starting: the abort behaviour depends on whether this flag was used.

Common traps

Done means