Some notable features of btrfs that make it stand above a regular ext4 partition:
Copy on write
Btrfs uses copy on write by default, on all copy operations. What this means is that if you take a eg. 20 GB file, make five copies of it, your free space is not going to be 100GB less, because the copies are just going to be references to the original file, they won't take up any space at all. When you start writing to the files, then they will start taking up space, but even then btrfs is clever enough to only store the modifications, instead of replicating the whole file. This is all done in the background, with you never noticing, which makes btrfs extremely efficient regarding free space.
There is a small drawback to this, standard utilities such as
df are going to report the free space incorrectly, you have to query the filesystem for that with
btrfs filesytem usage /.
Btrfs has a notion of subvolumes, which is very similar to partitions, but without an actual block device. Features of a subvolume:
- You can mount them as partitions
- You can take snapshots of it
- You can send them to other btrfs filesystems
For example, currently I use two subvolumes, one called "system" that is mounted on my /, and one called "home" mounted on /home. If you were to mount the btrfs partition (so not any of the subvolumes, but the partition itself), you would see this directory structure:
├── home -> fstab says mount this at /home ├── system -> fstab says mount this at / └── snapshots -> regular directory, see later
Obviously this is not bootable, but you don't mount the top level partition, you usually mount a subvolume as the root. My
fstab has a line like this for the root partition (note the subvolume flag at the end):
UUID=d6d9aaf0-dc1a-4440-bc1a-9dc21e7697ae / btrfs rw,noatime,compress=lzo,ssd,discard,space_cache,autodefrag,subvol=system 0 0
It's like my system runs in a chroot. If I were to leave out the
subvolume flag, I would actually get the aforementioned three directories as my /. Submodules enable some clever things, like you could set your database's data directory to point to a subvolume, and you could take snapshots of your database, or set up RAID1 over it (btrfs supports various kinds of RAID). The main point for me is that I can take separate snapshots of my system and home partition, so a borked system upgrade doesn't mean I have to roll back my personal stuff too.
A snapshot is a copy of the entire subvolume, that takes up zero space (ok, some space is needed for the metadata). You can have as many as you want, and you can even have snapshots of snapshots. A snapshot also acts as a subvolume, I don't even think there is any distinction between a snapshot and a subvolume after it has been created. This means that:
- You can take a snapshot of your system partition, before you do a system upgrade, and roll back your whole system easily if things break
- You can mount a snapshot, and copy stuff off from it.
- You can boot into a snapshot.
- You can take incremental snapshots by snapshotting snapshots
You can do extremely easy recovery if, for example a system upgrade messes everything up. You edit your fstab to boot into the snapshot (if it's so borked you can't even do that, you boot into a livecd, and edit fstab from there), mount your top level btrfs volume, rename the borked up system subvolume to "broken-shit", rename your snapshot to "system", edit your fstab so it mounts the system subvolume again, and boom, you have your whole system back, like it was before you did the system upgrade. All this takes a very little amount of space, because everything is copy on write. Taking a snapshot is just a matter of:
cd ~ # go into root's home mkdir btrfs-top # Create an empty folder mount /dev/sdaX btrfs-top # Mount the top level btrfs partition (this is the 3 directories from above) btrfs subvolume snapshot system btrfs-top/snapshots/before-sysupgrade # Create a snapshot umount btrfs-top
If you were to do to
ls -la btrfs-top/snapshots/before-sysupgrade after issuing the snapshot command, you would actually see your whole directory tree there. Creating the snapshot itself is instant, because it's just creating a bunch of references in the background. You could set up a cronjob/systemd timer to take a snapshot of your whole system every 5 minutes, and it would cost you very little amount of space. This is the most comfortable way I have found so far to deal with the "is this upgrade going to break everything" question.
Then there are some other niceties, like btrfs can use transparent compression when saving data, which results in less space used, and better performance (some caveats apply), and there is
btrfs send and
btrfs receive which allows you to send whole subvolumes to other disks, eg. when I had to replace an SSD in my laptop, it was trivial to copy over stuff with send/receive. Another wonderful thing is grub-btrfs, which automatically creates an entry in your grub menu for every snapshot you have. You install this hook, and you will be able to choose a snapshot from the boot menu, without changing anything in fstab.