TimeMachine corruption: Use btrfs 🙂

TimeMachine corruptionI do run TimeMachine backups from my MacBook to my Linux server, which is very convenient. However, I sometimes close the MacBook while the backup is going on and walk away. I believe this is the cause for the TimeMachine corruptions that I have once in a while. Even though I tried fixing these TimeMachine corruptions, I wasn’t always successful and I just hate the long reconstruction times.

Many of you with similar setups my have seen the dreaded error message:

Time Machine completed a verification of your backups on “Time Machine Volume”. To improve reliability, Time Machine must create a new backup for you.
Click Start New Backup to create a new backup. This will remove your existing backup history. This could take several hours.
Click Back Up Later to be reminded tomorrow. Time Machine won’t perform backups during this time.

I first tried to use my rsync backup script. However, this is very expensive, as it at least doubles the space required for the TimeMachine backups. Also, I do not want to prevent data loss or corruption on the linux server, so duplication seemed wasteful. What about copy-on-write?

As the backup was on a btrfs volume anyway,  one option would be to use deduplication. However, on Ubuntu 12.04 LTS, this is not easily done, as the kernel is too old. I did not want to play around with kernels, and did not find a version of rsync that uses the btrfs clone ioctl directly.

However, btrfs supports native (copy-on-write) snapshots. So I modified my rsync-backup.sh slightly:

# Usage: btrfs-backup.sh <src> <dst> <label>
if [ "$#" -ne 3 ]; then
    echo "$0: Expected 3 arguments, received $#: $@" >&2
    exit 1
if [ -d "$2/$3" ]; then
    btrfs subvolume delete "$2/$3"
btrfs subvolume snapshot "$1" "$2/$3"

Now, I just snapshot the entire (default) subvolume. It is syntactically call-compatible to rsync-backup.sh, but has slightly different restrictions:

  1. <src> needs to be a subvolume, either the default subvolume (i.e. the one created by mkfs.btrfs, generally the mountpoint) or a manually created subvolume (using btrfs subvolume create). So either clone the entire file system or create a subvolume and move everything into it. [1]I recommend the following sequence to move the a TimeMachine volume called atalk-volume into the newly created subvolume timemachine/ on the file system mounted at /srv/atalk/:
    service netatalk stop btrfs subvolume create /srv/atalk/timemachine cp –reflink=auto /srv/atalk/atalk-volume /srv/atalk/timemachine rm -rf /srv/atalk/atalk-volume vi /etc/netatalk/AppleVolumes.default # Edit the path service netatalk start
    The cp part does not require additional space at the time of copying, but it would when the original or the copy would start getting modified and I want to get rid of the old location anyway, therefore the rm
  2. <dst> may be on the same volume. Unlike the rsync approach, which requires <dst> to be outside the tree rooted at <src>, this can be inside the volume, as btrfs knows about the subvolume structure. Unless you have large amounts of frequently-written-to data, cloning the entire file system only takes marginally more space.




Let’s stay in touch!

Receive a mail whenever I publish a new post.

About 1-2 Mails per month, no Spam.

Follow me on the Fediverse

Web apps

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.