Optimizing SMB/SOHO Backups: A Btrfs-Enabled Solution with LVM Snapshots and rsync


15 views

With Btrfs now reaching production stability in Oracle EL (as of version 14) and gaining crucial tools like fsck and scrubbing capabilities since Linux 3.2, it's becoming a compelling choice for backup systems handling under 10TB of relatively static data (<1% daily changes). The copy-on-write architecture offers unique advantages:

# Example Btrfs subvolume creation
sudo btrfs subvolume create /backup/primary
sudo chown backupuser:backupgroup /backup/primary

The proposed solution follows four critical phases:

  1. LVM Snapshot Creation:
    lvcreate -L 10G -s -n db_snapshot_$(date +%Y%m%d) /dev/vg00/lv_db
  2. Delta Transfer via rsync:
    rsync -az --delete --numeric-ids --stats \
          --log-file=/var/log/backups/rsync_$(date +%Y%m%d).log \
          /mnt/snapshot/db/ backupuser@backupserver:/backup/primary/
  3. Btrfs Snapshotting:
    ssh backupuser@backupserver \
        "sudo btrfs subvolume snapshot -r /backup/primary /backup/snapshots/db_$(date +%Y%m%d)"
  4. Space Management:
    #!/bin/bash
    THRESHOLD=85
    while [ $(df /backup | awk 'NR==2{print $5}' | tr -d '%') -gt $THRESHOLD ]; do
        OLDEST=$(ls -1d /backup/snapshots/* | head -n 1)
        sudo btrfs subvolume delete "$OLDEST"
    done

While custom scripts work well, these solutions offer Btrfs awareness:

  • Bacula/Bareos: Configure FileSet with @Btrfs plugin
  • BackupPC: Modify rsync_bpc to handle subvolumes
  • ZFS-like Approaches: Many ZFS backup users employ zfs send/receive equivalents like:
    btrfs send /backup/snapshots/db_20230101 | \
        ssh backup2 "btrfs receive /remote/backup"

Exposing snapshots via Samba with VSS support:

[Previous Versions]
path = /backup/snapshots
read only = yes
browseable = yes
vfs objects = shadow_copy2
shadow: snapdir = .snapshots
shadow: sort = desc
shadow: format = _%Y-%m-%d_%H:%M:%S_

Implement periodic data integrity checks:

# Weekly scrub
echo "0 3 * * 0 root /usr/bin/btrfs scrub start -Bd /backup" > /etc/cron.d/btrfs-scrub

# Filesystem check after 30 snapshots
counter=0
find /backup/snapshots -maxdepth 1 -type d | while read -r snap; do
    ((counter++))
    if [ $counter -ge 30 ]; then
        btrfs check --readonly "$snap"
        counter=0
    fi
done

With Oracle EL 14 bringing production-ready Btrfs support (including fsck and scrubbing from Linux 3.2+), we're seeing a perfect storm for implementing efficient backup solutions. For environments handling under 10TB of relatively static data (less than 1% daily changes), Btrfs offers compelling advantages:

# Key Btrfs features for backup:
- Copy-on-write snapshots (KB-level overhead)
- Built-in checksums and data scrubbing
- Transparent compression options
- Subvolume management for retention policies

Here's the complete workflow with implementation examples:

  1. LVM Snapshot Creation:
    lvcreate -L 10G -s -n db_snap /dev/vg00/lv_db
    mount /dev/vg00/db_snap /mnt/snapshot
  2. Rsync with Btrfs-aware Options:
    rsync -avz --delete --inplace --no-whole-file \
    --fake-super /mnt/snapshot/ btrfs-backup:/backups/daily/
  3. Btrfs Snapshot Creation:
    btrfs subvolume snapshot -r /backups/daily \
    /backups/snapshots/$(date +%Y%m%d)
  4. Automated Snapshot Rotation:
    #!/bin/bash
    MAX_SNAPS=30
    snapshots=($(btrfs subvolume list /backups | sort -r))
    if [ ${#snapshots[@]} -gt $MAX_SNAPS ]; then
        for snap in "${snapshots[@]:$MAX_SNAPS}"; do
            btrfs subvolume delete "/backups/$snap"
        done
    fi

For those considering existing backup systems with Btrfs support:

Solution Btrfs Integration SMB Suitability
Bacula Manual snapshot handling Enterprise
BackupPC No native CoW support Mid-range
BorgBackup Deduplication only All sizes
Custom Rsync Full control SMB/SOHO

For those coming from ZFS environments, here's the Btrfs equivalent of common operations:

# ZFS snapshot → Btrfs equivalent
zfs snapshot tank/data@monday → btrfs subvolume snapshot -r /data /data/.snapshots/monday

# ZFS send/receive → Btrfs send/receive
zfs send tank/data@monday | ssh backup zfs receive → btrfs send /data/.snapshots/monday | ssh backup btrfs receive /backups

# ZFS scrub → Btrfs scrub
zpool scrub tank → btrfs scrub start /data

For optimal performance in backup scenarios:

# /etc/fstab entry for backup volume:
UUID=xxxx-xxxx /backups btrfs noatime,compress=zstd:3,space_cache=v2,autodefrag 0 0

# Weekly scrub cronjob:
0 3 * * 0 /usr/bin/btrfs scrub start -Bd /backups

The compress=zstd:3 setting provides excellent compression ratios for backup data without significant CPU overhead.