Experiments with Btrfs RAID1

Created: 2022-02-02
Updated: 2022-02-02

RAID1 is a data replication technique that stores two copies of data on two different disks, providing fault tolerance and high availability in case one of the disks fails.

With btrfs, you can create a RAID1 array by combining two or more devices. The devices can be physical disks or partitions.

Loopback devices preparation

To make experimentation more agile, I’ll use loopback devices instead of physical devices.

These steps are not required if working on real devices.

Create a 1 GiB file to act as our physical drive.

$ dd bs=1G count=1 if=/dev/zero of=hd0

Create the loopback device

$ losetup /dev/loop0 hd0

To remove the loopback device at the end of experiments

$ losetup -d /dev/loop0

Repeat the procedure for another disk (hd1) and

Check the devices

$ losetup -a

Creating RAID1 storage

Create the btrfs filesystems

$ mkfs.btrfs -L myraid /dev/loop0
$ mkfs.btrfs -L myraid /dev/loop1

Method #1 : incremental

Mount the first drive

$ mount /dev/loop0 /mnt/raid

$ btrfs filesystem show /mnt/raid
Label: myraid  uuid: 7a1b8dc3-4b19-48f7-ba04-a99179ed9d08
        Total devices 1 FS bytes used 2.02MiB
        devid    1 size 1.00GiB used 126.38MiB path /dev/loop0

Copy some files to the mounted hard drive (used to verify synchronization)

Add the second drive, resulting in combined storage capacity spanned across both drives (i.e. RAID0).

$ btrfs device add /dev/loop1 /mnt/raid

$ btrfs filesystem show /mnt/raid
Label: myraid  uuid: 7a1b8dc3-4b19-48f7-ba04-a99179ed9d08
        Total devices 2 FS bytes used 2.02MiB
        devid    1 size 1.00GiB used 126.38MiB path /dev/loop0
        devid    2 size 1.00GiB used 0.00B path /dev/loop1

$ btrfs filesystem df /mnt/raid
Data, single: total=8.00MiB, used=1.41MiB
System, DUP: total=8.00MiB, used=16.00KiB
Metadata, DUP: total=51.19MiB, used=608.00KiB
GlobalReserve, single: total=3.25MiB, used=0.00B

Convert to RAID1 both for data and metadata.

$ btrfs balance start -m convert=raid1 -d convert=raid1 /mnt/raid

$ btrfs filesystem show /mnt/raid
Label: myraid  uuid: 7a1b8dc3-4b19-48f7-ba04-a99179ed9d08
        Total devices 2 FS bytes used 2.02MiB
        devid    1 size 1.00GiB used 480.00MiB path /dev/loop0
        devid    2 size 1.00GiB used 480.00MiB path /dev/loop1

$ btrfs filesystem df /mnt/raid
Data, RAID1: total=208.00MiB, used=1.41MiB
System, RAID1: total=64.00MiB, used=16.00KiB
Metadata, RAID1: total=208.00MiB, used=608.00KiB
GlobalReserve, single: total=3.25MiB, used=0.00B

Method #2 : direct

$ mkfs.btrfs -L myraid -m raid1 -d raid1 /dev/loop0 /dev/loop1

Degraded mode

In case that one of the disks failed, then mount the remaining device in degraded mode.

Simulate a faulty disk by detaching one of the two loopback devices:

$ umount /mnt/raid
$ losetup -d /dev/loop1

$ mount /dev/loop0 /mnt/raid
mount: /mnt/raid: wrong fs type, bad option, bad superblock on /dev/loop0, \
missing codepage or helper program, or other error.

$ btrfs filesystem show /dev/loop0
warning, device 1 is missing
Label: none  uuid: 7a1b8dc3-4b19-48f7-ba04-a99179ed9d08
        Total devices 2 FS bytes used 2.02MiB
        devid    2 size 1.00GiB used 592.00MiB path /dev/loop0
        *** Some devices missing

Mount in degraded mode the available device

$ btrfs -o degraded /dev/loop0 /mnt/raid

Replace faulty disk

Create another bare new device surrogate (this is obviously not required if we are working with real storage devices).

$ dd if=/dev/zero of=hd2 bs=1G count=1
$ losetup /dev/loop2 hd2

Add the new device to the RAID1 array.

$ btrfs device add /dev/loop2 /mnt/raid
Performing full device TRIM /dev/loop2 (1.00GiB) ...
WARNING: Multiple block group profiles detected, see 'man btrfs(5)'.
WARNING:   Metadata: single, raid1
WARNING:   System: single, raid1

Remove missing device

$ btrfs device delete missing /mnt/raid

Finally, balance data to spread exactly the same data to the new device.

$ btrfs filesystem balance /mnt/raid

Check mirroring is completed

$ btrfs filesystem show
Label: myraid  uuid: 7a1b8dc3-4b19-48f7-ba04-a99179ed9d08
        Total devices 2 FS bytes used 2.02MiB
        devid    2 size 1.00GiB used 688.00MiB path /dev/loop1
        devid    3 size 1.00GiB used 688.00MiB path /dev/loop2