ZFS: Maintenance

Migrate from one ZFS mirror to another

by ross at 12:50:46 on October 20, 2016

The hardware

The previous page shows how to replace a failed drive. But what if the drives are very old and you simply do not have a replacement?

This is how you can migrate the data from the old mirror to a new one (a new pair of disks).

OK, I had two ancient WD Raptors in this server: ada1 (gpt/swap0 and gpt/system0) and ada2 (gpt/swap1 and gpt/system1). The first one died, so I decided to replace both of them with modern WD RE drives.

When ada1 died the system became painfully slow so the first commands I had to run were these (pool's name is system):

# zpool detach system gpt/system0
# swapoff /dev/gpt/swap0

For a couple of days the system was running on just one drive. When the new drives were finally delivered I shutdown the machine, thrown away the dead Raptor, moved the survived one to ada3 and connected the new drives as ada1 and ada2.

Import the old mirror, prepare the new one

Boot from FreeBSD 9.0 DVD (or whatever version you installed), choose “Shell” when it asks what to do.

First, import the old mirror. Because I am going to create the new mirror with the same name (“system”) as the old one, I had to import the original mirror like this:

# mkdir /tmp/old
# zpool import -f -R /tmp/old system old

So the system mirror is imported with the name old under /tmp/old.

Now create the partitions just like shown here:

I do not create swap partitions as I decided to dedicate the survived drive to that. But you probably will want to create the swap on your new drives.

# gpart create -s gpt ada1
# gpart add -b 34 -s 512k -t freebsd-boot ada1
# gpart add -t freebsd-zfs -l system2 ada1

# gpart create -s gpt ada2
# gpart add -b 34 -s 512k -t freebsd-boot ada2
# gpart add -t freebsd-zfs -l system3 ada2

# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada2
# zpool create -m none -o altroot=/mnt \
               -o cachefile=/var/tmp/zpool.cache \
               system mirror /dev/gpt/system2 /dev/gpt/system3
# zfs set mountpoint=/ system

Move the data

# zfs snapshot -r old@safe
# zfs send -R old@safe | zfs receive -F system
# zfs destroy -r system@safe

All the data including existing snapshots is copied. Confirm:

# zpool iostat
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
old         22.5G  9.71G    222      4  8.49M  34.1K
system      22.5G   209G     32    593  85.1K  9.68M
----------  -----  -----  -----  -----  -----  -----

You see that the same amount of data is allocated on both the mirrors. Finally, prepare the new mirror to boot:

# zpool set bootfs=system system
# mkdir -p /mnt/boot/zfs
# cp /var/tmp/zpool.cache /mnt/boot/zfs/zpool.cache

Now shutdown, unplug the survived drive and boot from one of the new drives.

After you make sure everything is OK you can connect the survived drive again, boot from DVD and delete the partitions on it with gpart.