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


5 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.