]> BTRFS - Snapshot rollback 🌐:aligrant.com

BTRFS - Snapshot rollback

Alastair Grant | Monday 25 November 2013

I was trying to clean up my user directory backup - which I currently rsync and then do periodic snapshots of. I realised that I wasn't deleting old files in my destination and I had a bunch of temp files that I didn't need to include. In my bid to sort out the links I managed to wipe out a lot of data on my backup.

When I ran rsync again it started trying to move gigs of photos over - not something I fancied doing and also lead me to wonder, if I:

  1. Create a file
  2. Snapshot the file
  3. Delete the original file
  4. Re-create the original file with an identical copy

Would the 'btrfs' snapshot store the file twice? Unless it was very clever, I suspected it would. A quick drop in on #btrfs on Freenode confirmed my thoughts. By re-running my backups from scratch would make my next snapshot a complete duplication of all the data that was there before. So in addition to taking a long time, I would lose a lot of space. Lucky for me, I have period snapshots that I can roll back to.

Everybody knows that they should keep backups of their data and have disaster recovery and rollback options when it comes to IT. Many people and organisations get the backups but a fewer number test the recovery of that data. If you cannot revert your data then what's the point in the backup? This was my first real-world attempt to rollback a 'btrfs' subvolume.

My first port-of-call was the program that manages my backups - "Snapper". This creates hourly backups and has a built-in undochanges command - which I ran. Everything back to how it was, I kicked of my 'rsync' job again but was confused to see all my files being re-copied. After a bit of investigation it turns out that Snapper does not retain timestamps when it does a rollback (WHY!?!?). A manual rollback is therefore required. I began to brain-freeze when I realised that the snapshots were in a subdirectory of the directory I wanted to rollback. Still, I crossed my fingers and started running commands:

mv mydirectory mydirectory.old
btrfs subvolume snapshot mydirectory.old/.snapshots/20/snapshot mydirectory
mv mydirectory.old/.snapshots mydirectory/
rm -rf mydirectory.old

What this does is:

  1. Moves the old subvolume out of the way - this should be instant as no data is moved, just the reference
  2. Takes a snapshot of the snapshot that I want to recover and puts it in place of the original subvolume
  3. Move all my other snapshots into the new subvolume
  4. Delete the old subvolume

This all works because snapshots are subvolumes. By moving directories I appear to be essentially creating links to different subvolumes. As each snapshot is exactly that, a snapshot of the entire directory, we can delete the originals without issue.

Useful to know!

Breaking from the voyeuristic norms of the Internet, any comments can be made in private by contacting me.