I'm rearranging a bunch of disks on my server at home and I find myself in the position of wanting to move a bunch of LVM logical volumes to another volume group. Is there a simple way to do this? I saw mention of a cplv command but this seems to be either old or not something that was ever available for Linux.
- 13,477
- 385
4 Answers
If you can arrange for the logical volume to be on a separate subset of physical volumes from the rest of the source volume group (lvconvert sourcevg/sourcelv /dev/pv1 ... may help), you can use vgsplit to split off the lv into a new vg and vgmerge to merge the new vg into the target vg.
Although LVM has a mirroring feature, you can't (sanely) use it to make a copy between volume groups, because both legs of the mirror must live on the same vg and the association can't be broken.
You can copy an LVM volume to another the way you'd copy any volume to another: create a target lv of the appropriate size, then copy the contents with dd if=/dev/sourcevg/sourcelv of=/dev/targetvg/targetlv bs=4M. If the source volume is active, you can leverage LVM to make a consistent copy: first take a snapshot of the source lv with lvcreate -s, then copy the snapshot.
- 4,777
- 72,151
As of the LVM in Debian stretch (9.0), namely 2.02.168-2, it's
possible to do a copy of a logical volume across volume groups using a combination of vgmerge, lvconvert, and vgsplit. Since a move is a combination of a copy and a delete, this will also work for a move.
Alternatively, you can use pvmove to move the physical extents instead. To quote U&L: Purpose of Physical Extents:
A single physical extent is the smallest unit of disk space that can be individually managed by LVM.
A complete self-contained example session using loop devices and
lvconvert follows.
Summary: we create volume group vg1 with logical volume lv1, and vg2 with lv2, and make a copy of lv1 in vg2.
Create files.
truncate pv1 --size 100MB
truncate pv2 --size 100MB
Set up loop devices on files.
losetup /dev/loop1 pv1
losetup /dev/loop2 pv2
Create physical volumes on loop devices (initialize loop devices for use by LVM).
pvcreate /dev/loop1 /dev/loop2
Create volume groups vg1 and vg2 on /dev/loop1 and /dev/loop2 respectively.
vgcreate vg1 /dev/loop1
vgcreate vg2 /dev/loop2
Create logical volumes lv1 and lv2 on vg1 and vg2 respectively.
lvcreate -L 10M -n lv1 vg1
lvcreate -L 10M -n lv2 vg2
Create ext4 filesystems on lv1 and lv2.
mkfs.ext4 -j /dev/vg1/lv1
mkfs.ext4 -j /dev/vg2/lv2
Optionally, write something on lv1 so you can later check the copy was correctly created. Make vg1 inactive.
vgchange -a n vg1
Run merge command in test mode. This merges vg1 into vg2.
vgmerge -A y -l -t -v <<destination-vg>> <<source-vg>>
vgmerge -A y -l -t -v vg2 vg1
And then for real.
vgmerge -A y -l -v vg2 vg1
Then create a RAID 1 mirror pair from lv1 using lvconvert. The
dest-pv argument tells lvconvert to make the mirror copy
on /dev/loop2.
lvconvert --type raid1 --mirrors 1 <<source-lv>> <<dest-pv>>
lvconvert --type raid1 --mirrors 1 /dev/vg2/lv1 /dev/loop2
Then split the mirror. The new LV is now lv1_copy.
lvconvert --splitmirrors 1 --name <<source-lv-copy>> <<source-lv>>
lvconvert --splitmirrors 1 --name lv1_copy /dev/vg2/lv1
Make vg2/lv1 inactive.
lvchange -a n /dev/vg2/lv1
Then (testing mode)
vgsplit -t -v <<source-vg>> <<destination-vg>> <<moved-to-pv>>
vgsplit -t -v /dev/vg2 /dev/vg1 /dev/loop1
For real
vgsplit -v /dev/vg2 /dev/vg1 /dev/loop1
Resulting output:
lvs
[...]
lv1 vg1 -wi-a----- 12.00m
lv1_copy vg2 -wi-a----- 12.00m
lv2 vg2 -wi-a----- 12.00m
NOTES:
Most of these commands will need to be run as root.
If there is any duplication of the names of the logical volumes in the two volume groups,
vgmergewill refuse to proceed.On merge, logical volumes in
vg1must be inactive. And on split, logical volumes invg2belonging tovg1must be inactive. In our case, this islv1.
- 520
pvmove -n lvol1 /dev/sdb1 /dev/sdc1
pvmove can move data between physical volumes: LVM Administrator's Guide
- 167
"pvmove -n lvol1 /dev/sdb1 /dev/sdc1" should work if you had both disks in the same volume group... otherwise it would fail with this error
pvmove -v -n vm-100-disk-1 /dev/sda3 /dev/sdb1
Physical Volume "/dev/sdb1" not found in Volume Group "pve".
It may also fail if the LV is thin (eg: defaults of Proxmox), as PVMove assumes LINEAR type.
lvdisplay -m
--- Logical volume ---
LV Path /dev/pve/vm-100-disk-1
LV Name vm-100-disk-1
VG Name pve
LV Pool name data
LV Size 100.00 GiB
Current LE 25600
Segments 1
--- Segments ---
Virtual extents 0 to 25599:
Type thin
Whereas a thick volume:
--- Logical volume ---
LV Path /dev/pve/swap
...
--- Segments ---
Logical extents 0 to 2047:
Type linear
Physical volume /dev/sda3
Physical extents 0 to 2047
You cannot convert it either
lvconvert --type linear /dev/pve/vm-100-disk-1
Operation not permitted on LV pve/vm-100-disk-1 type thin.
If you try to PVMove a Thin Volume to a different PV (disk) ... it gives error message
pvmove -v -n vm-100-disk-1 /dev/sda3 /dev/sdb1
Creating logical volume pvmove0
No data to move for pve.
So, the solution to the OP, regardless of LV type or where the PV exists (different VG), is to 1 - Create a PV on a spare disk 2 - use DD to move the data, 3 - remove old LV, 4 - rename new LV to the same as the old
# format disk partition as LVM
pvcreate /dev/sdX1
add new PV to a new VG (or re-use an existing VG)
vgcreate VOLGROUP /dev/sdX1
Create new LV
lvcreate -L 100G -n vm-100-disk-1-NEW VOLGROUP
migrate data over, now it will be thick
dd if=/dev/pve/vm-100-disk-1 of=/dev/VOLGROUP/vm-100-disk-1-NEW bs=1M conv=fdatasync status=progress
you may want to double check your new data is good first
remove the old data
lvremove -v pve/vm-100-disk-1
rename the new LV into the old name
lvrename /dev/VOLGROUP/vm-100-disk-1-NEW /dev/VOLGROUP/vm-100-disk-1
More information on Thin Volumes inside Thin Pools and moving data
- 1,443