I recently discussed how to use LVM to make a live copy of a BackupPC pool. That guide covers how to set up LVM on a new server with no data. But what if you already have a working BackupPC install, and you want to move your existing pool to LVM?
I wrote a post 18 months ago on moving a Linux root partition to software RAID. Moving to LVM shares a lot of the same problems. The differences are:
- We’re not touching the root (or /boot) filesystem. Therefore we don’t have to deal with BIOS or GRUB. In fact, this entire process can be done without rebooting.
- We must copy the filesystem bit-for-bit instead of using file-aware tools like rsync, cp, or tar. This is due to the design of the BackupPC storage pool.
If you have another disk to use as a swap space, this problem is easy to solve. Simply unmount your backuppc partition and use dd to clone the data to the new drive. Then make create a logical volume on the old partition and copy it back.
If you don’t have another disk, you must convert the disk layout in place. The instructions in this post can be used to move any filesystem to LVM; just disregard the parts specific to BackupPC. I assume that your server’s drive and filesystem layout is as described in my last post:
- /dev/sda provides the root filesystem (and possibly others). We’re not concerned about it here.
- /dev/sdb is a RAID array with one partition. It does not yet use LVM, and contains an ext3 filesystem mounted on /var/lib/backuppc.
The general plan is:
- Reduce filesystem usage on /var/lib/backuppc to 49% or less
- Resize the filesystem and partition to 49%
- Create a second partition and logical volume with the free space
- Copy the filesystem to the logical volume
- Add the first partition to the logical volume
- Expand the logical volume and filesystem
- Mount the logical volume
Warning: this is a multi-day process with many long delays for large data transfers. I’ll identify the delays as we go along. Never interrupt a filesystem operation unless you know exactly what you are doing. I recommend executing all long-running processes in a GNU screen session in case your network connection is interrupted.
Step 1: Reduce filesystem usage on /var/lib/backuppc to 49% or less
If your BackupPC pool filesystem is larger than 49%, you must reduce disk usage.
- Remove old backups. Reduce the BackupPC variables $Conf{FullKeepCnt} and $Conf{IncrKeepCnt} to keep fewer backups. Alternately, use a script like BackupPC_deleteBackup.sh to delete old ones manually.
- Set $Conf{BackupPCNightlyPeriod} = 1
- Wait for the next BackupPC_Nightly run. BackupPC will purge old backups and clean the pool of unnecessary files. This may take several days, but during this time you can perform backups as normal.
Do not proceed until filesystem usage is below 49%. Verify this with df.
Step 2: Resize the filesystem and partition to 49%
You may wish to read this guide first. It is possible to use the parted “resize” function for this, but it doesn’t work for all filesystems. We’ll do it manually.
- Stop BackupPC. From this point no new backups will be kept until the entire process is finished, which may be several days.
/etc/init.d/backuppc stop - Unmount the partition
umount /var/lib/backuppc - Get the block size and block count for the partition, and calculate the new size in K.
tune2fs -l /dev/sdb1 | grep BlockBlock count: 2620595 Block size: 4096
I’ve used a 10 GB partition in this example, and we now know that this filesystem consists of 2620595 blocks of 4K size. Calculate the new size as follows:
new size = (current size in blocks) * (block size in K) * 0.49
Round this number down. Our new size will be 2620595 * 4 * 0.49 = 5136366 K.
- Check the filesystem. This may take several hours or days.
fsck -f /dev/sdb1 - Resize the filesystem.
resize2fs /dev/sdb1 5136366Kresize2fs 1.40.8 (13-Mar-2008) Resizing the filesystem on /dev/sdb1 to 1284091 (4k) blocks. The filesystem on /dev/sdb1 is now 1284091 blocks long.
- Resize the partition by deleting it and creating a new one of 5136366K.
fdisk /dev/sdbCommand (m for help): p Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x0005eeec Device Boot Start End Blocks Id System /dev/sdb1 1 1305 10482381 83 Linux Command (m for help): d 1 Selected partition 1 Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-1305, default 1): Using default value 1 Last cylinder or +size or +sizeM or +sizeK (1-1305, default 1305): +5136366K Command (m for help): p Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x0005eeec Device Boot Start End Blocks Id System /dev/sdb1 1 640 5140768+ 83 Linux Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.
Step 3: Create a second partition and logical volume with the free space
- If you haven’t already, install LVM.
apt-get install lvm2 - Use fdisk again to create a second partition. You can combine this step with the last one. Hit enter at the prompts to use all available space, and change the new partition to type 8e, Linux LVM.
fdisk /dev/sdbCommand (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First cylinder (641-1305, default 641): Using default value 641 Last cylinder or +size or +sizeM or +sizeK (641-1305, default 1305): Using default value 1305 Command (m for help): p Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x0005eeec Device Boot Start End Blocks Id System /dev/sdb1 1 640 5140768+ 83 Linux /dev/sdb2 641 1305 5341612+ 83 Linux Command (m for help): t Partition number (1-4): 2 Hex code (type L to list codes): 8e Changed system type of partition 2 to 8e (Linux LVM) Command (m for help): p Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x0005eeec Device Boot Start End Blocks Id System /dev/sdb1 1 640 5140768+ 83 Linux /dev/sdb2 641 1305 5341612+ 8e Linux LVM Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.
- The second partition must be equal to or larger than the first partition. If it is not, check your math or try resizing to a smaller percentage and try again.
- Create a volume group and logical volume.
pvcreate /dev/sdb2
vgcreate volgroup /dev/sdb2
lvcreate -l 100%VG -n backuppc volgroup
Step 4: Copy the filesystem to the logical volume
- Use dd, the sysadmin’s oldest friend, to copy the filesystem bit-for-bit from the old partition to the new. This may take several hours or days.
dd if=/dev/sdb1 of=/dev/volgroup/backuppc - If you get impatient during the copy, you can force dd to output the current progress. Find the process ID of the running dd, and send a USR1 signal.
ps -ef | grep ddroot 4786 4642 26 15:44 pts/0 00:00:01 dd if /dev/sdb1 of /dev/volgroup/backuppc
kill -USR1 478618335302+0 records in 18335302+0 records out 9387674624 bytes (9.4 GB) copied, 34.6279 seconds, 271 MB/s
- A neater way to do this is:
dd if=/dev/sdb1 of=/dev/volgroup/backuppc &
pid=$!
kill -USR1 $pid - When dd finishes you will see one last progress report which should total the size of /dev/sdb1.
Step 5: Add the first partition to the logical volume
We’ve copied our data to the logical volume, so we no longer need the original partition. Add it to the volume group.
- Use fdisk to change partition 1 to type 8e.
fdisk /dev/sdbCommand (m for help): p Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x0005eeec Device Boot Start End Blocks Id System /dev/sdb1 1 640 5140768+ 83 Linux /dev/sdb2 641 1305 5341612+ 8e Linux LVM Command (m for help): t Partition number (1-4): 1 Hex code (type L to list codes): 8e Changed system type of partition 1 to 8e (Linux LVM) Command (m for help): p Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x0005eeec Device Boot Start End Blocks Id System /dev/sdb1 1 640 5140768+ 8e Linux LVM /dev/sdb2 641 1305 5341612+ 8e Linux LVM Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.
- Add it to the volume group.
pvcreate /dev/sdb1
vgextend volgroup /dev/sdb1
Step 6: Expand the logical volume and filesystem
We’ve moved the data to a logical volume and added all the disk space to the volume group. Now we expand the logical volume and filesystem to use the available space.
- Extend the logical volume. I advise using only 75% so you can use LVM snapshots.
lvextend -l 75%VG /dev/volgroup/backuppc - Resize the filesystem to use the entire logical volume. This may take several hours or days.
resize2fs /dev/volgroup/backuppc - If at any point you’ve mounted the filesystem, you’ll have to run a new fsck before resizing. This will cause another long delay, so try to avoid it.
Step 7: Mount the logical volume
We’re now ready to mount the new logical volume on /var/lib/backuppc and restart BackupPC.
- Edit /etc/fstab and replace any references to /dev/sdb1 with /dev/volgroup/backuppc. If your fstab uses UUIDs instead of explicit device paths, you shouldn’t have to change anything.
- Mount the filesystem.
mount /var/lib/backuppc - Restart BackupPC
/etc/init.d/backuppc start
You have successfully migrated to LVM!
Leave a Reply