I think that most of your questions can be answered simply by remembering that in Btrfs, a snapshot is not really special, it's just a Btrfs subvolume. It just happens that when it's created, it has initial contents instead of being empty, and the storage space for those initial contents is shared with whatever subvolume the snapshot came from.
A snapshot is just like a (full) copy, except it's more economical because of the shared storage.
- If I don't do snapshots, can you roll back a single file to several changes ago?
No. Just like with any regular filesystem, modifying files is destructive. You can't magically go back to an earlier version.
- Can btrfs snapshots of root be used and thought of just like VMware/VirtualBox snapshots?
VM disk images are usually block devices, not filesystems or files on filesystems, so I think it's a little different.
You could use a Btrfs file as backing store for a VM virtual block device, I guess. In which case the answer to that question is yes. Except if you use the NOCOW option (which is actually recommended for disk images). Then probably not, because copy-on-write is the magic that makes snapshots work.
- I label snapshot A, make changes and label it B. If I go back to snapshot A and make changes (even just by booting changing /var/log), are those changes made in a "detached" or "unlabeled" snapshot, so those changes would be invisible if going back to B?
Every subvolume (including snapshots) in Btrfs has a name, so you cannot have an "unlabeled" snapshot.
In general, any changes you make in one Btrfs subvolume (whether it was created as a snapshot or not) are absolutely not ever visible in another Btrfs subvolume. Just remember that a snapshot is just like a copy, but more economical.
- When deleting a file, is there "this file is deleted" metadata written, so space is still taken by all the versions of the file?
When deleting a file, its directory entry is removed. That is a modification to the directory, and like all modifications, it will be private to the subvolume in which it occurred. Then after that, if and only if the storage space for the file is not used by any other part of the filesystem, it's freed.
Deleting a file whose storage is shared between multiple snapshots is a lot like deleting a file in any regular filesystem when it has multiple (hard) links. The storage [inode] is freed iff it is not referenced anymore.
- If I build gcc from source, as an example, I think the build directory winds up being 5-8GB. If I build it periodically from source, I'm "chewing up" a bunch of hard drive space, right?
If you build gcc
multiple times in multiple different directories, then yeah, it will use more and more space. If you delete copies in between builds or overwrite the same build directory each time, then, no, there's no particular reason why it would keep using more and more space.
Best Answer
The replace command doesn't make a backup of sda1, it replaces sda1 with sdb1 in the filesystem, but since it's a one device filesystem and btrfs doesn't bother wiping the data from sda1 when it replaces it they end up being indentical copies of the filesystem. However you do NOT want to do this as both will have the same UUID, and currently it's not safe to mount two btrfs filesystems with the same UUID as it can cause MASSIVE DATA CORRUPTION (see btrfswiki's Gotchas page). If you want to use btrfs's incremental backup feature you should format you're backup drive /dev/sdb1 to a new btrfs filesystem. Then you should make a read-only snapshot of watever subvolume(s) you want to backup on your filesystem by using
on each subvolume. Then you should mount the blank btrfs filesystem and run
This will be the first send and btrfs will have to transfer all of the data this time. Next time you want to send a backup to this drive you can use incremental sends to only send what data has changed since the previous backup you sent. It will also use Copy On Write so you'll save a lot of space as well. Just make sure you keep the latest snapshot on both filesystems. When it's done you can rename the sent snapshot to whatever you want.
Now if you want to send another snapshot just rename the orignal one and take a new snapshot with something like
Then you can use send to send the latest snapshot using
and if the previous snapshot still exists on your backup drive it will send your new snapshot by only having to copy whatever changes you've made since the previous one.