Btrfs

How to Use Btrfs Snapshots

The Btrfs filesystem has built-in filesystem-level snapshot support. You can create a subvolume in your Btrfs filesystem and take snapshots of the files/directories in that subvolume. Taking a snapshot of a subvolume will save the state of the files/directories in that subvolume. You can recover any files/directories of the subvolume from the snapshot in case you need it.

The snapshot feature of the Btrfs filesystem uses the Copy-on-Write (CoW) principle. So, it does not take much disk space, and you can take snapshots of a subvolume instantly.

The Btrfs filesystem supports 2 types of snapshots.

  1. Writable snapshots: If you take a writable snapshot, you can modify that snapshot’s files/directories later. This is the default snapshot type of the Btrfs filesystem.
  2. Read-only snapshots: If you take a read-only snapshot, you can’t modify that snapshot’s files/directories later.

This article will show you how to take writable and read-only snapshots of your Btrfs filesystem subvolumes. I will also show you how to update a writable snapshot and recover files from a snapshot. I will show you how to remove a snapshot as well. So, let’s get started.

Prerequisites

To try out the examples of this article,

  • You must have the Btrfs filesystem installed on your computer.
  • You need to have a hard disk or SSD with at least 1 free partition (of any size).

I have a 20 GB hard disk sdb on my Ubuntu machine. I have created 2 partitions sdb1 and sdb2 on this hard disk. I will use the partition sdb1 in this article.

$ sudo lsblk -e7

Your hard disk or SSD may have a different name than mine, so will the partitions. So, make sure to replace them with yours from now on.

If you need any assistance on installing the Btrfs filesystem on Ubuntu, check my article Install and Use Btrfs on Ubuntu 20.04 LTS.

If you need any assistance on installing the Btrfs filesystem on Fedora, check my article Install and Use Btrfs on Fedora 33.

Creating a Btrfs Filesystem

To experiment with Btrfs subvolumes, you need to create a Btrfs filesystem.

To create a Btrfs filesystem with the label data on the sdb1 partition, run the following command:

$ sudo mkfs.btrfs -L data /dev/sdb1

A Btrfs filesystem should be created.

Create a directory /data with the following command:

$ sudo mkdir -v /data

To mount the Btrfs filesystem created on the sdb1 partition in the /data directory, run the following command:

$ sudo mount /dev/sdb1 /data

The Btrfs filesystem should be mounted as you can see in the screenshot below.

$ df -h /data

Preparing the Btrfs Filesystem for Snapshots

In Btrfs, you can take snapshots of Btrfs subvolumes only. The main root of a Btrfs filesystem is also a subvolume. So, you can take the backup of the entire Btrfs filesystem as well as specific subvolumes.

This section will create a Btrfs subvolume /data/projects/web1 and create the necessary files for the next sections of this article below. I will also create a directory where you can keep your snapshots. In the next sections, I will show you how to take snapshots (writable and read-only), update a writable snapshot, and recover files from the snapshot. So, let’s get started.

First, create a new directory /data/projects as follows:

$ sudo mkdir -v /data/projects

Create a new subvolume web1 in the /data/projects directory as follows:

$ sudo btrfs subvolume create /data/projects/web1

Create a new file index.html in the /data/projects/web1 subvolume as follows:

$ sudo nano /data/projects/web1/index.html

Type in the following lines of codes in the index.html file.

<!DOCTYPE html>
<html>
<head>
    <title>Demo Website</title>
    <link rel="stylesheet" href="style.css"/>
</head>
<body>
    <h1>Hello World 4</h1>
</body>
</html>

Once you’re done, press <Ctrl> + X followed by Y and <Enter> to save the index.html file.

Create a new file style.css in the /data/projects/web1 subvolume as follows:

$ sudo nano /data/projects/web1/style.css

Type in the following lines of codes in the style.css file.

h1 {
color: green;
}

Once you’re done, press <Ctrl> + X followed by Y and <Enter> to save the style.css file.

Now, the /data/projects/web1 subvolume has the index.html and style.css file.

$ ls -lh /data/projects/web1

I want to keep all the snapshots of this Btrfs filesystem in the /data/.snapshots directory.

Create the /data/.snapshots directory with the following command:

$ sudo mkdir -v /data/.snapshots

Taking Snapshots of a Subvolume

To take a snapshot of the /data/projects/web1 subvolume into the /data/.snapshots/web1-2020-12-25 directory (will be created automatically), run the following command:

$ sudo btrfs subvolume snapshot /data/projects/web1 /data/.snapshots/web1-2020-12-25

A snapshot of the /data/projects/web1 directory should be created on the /data/.snapshots/web1-2020-12-25 directory.

As you can see in the screenshot below, a new subvolume .snapshots/web1-2020-12-25 is created. A snapshot is actually a subvolume.

$ sudo btrfs subvolume list /data

You can see more information about the snapshot you’ve created in the /data/.snapshots/web1-2020-12-25 directory as follows:

$ sudo btrfs subvolume show /data/.snapshots/web1-2020-12-25

As you can see, all the files that are in the /data/projects/web1 subvolume are in the /data/.snapshots/web1-2020-12-25 snapshot.

$ tree -a /data

Recovering Files from Snapshots

In this section, I am going to show you how to recover files from the Btrfs snapshots.

First, I am going to show you how to recover a single file from the snapshot.

Open the /data/projects/web1/index.html file with the nano text editor as follows:

$ sudo nano /data/projects/web1/index.html

Make any changes you want.

Once you’re done, press <Ctrl> + X followed by Y and <Enter> to save the file.

As you can see, the main index.html file is different from the index.html file in the snapshot.

$ cat /data/projects/web1/index.html
$ cat /data/.snapshots/web1-2020-12-25/index.html

We have made the changes to the main index.html file are unwanted, and we want to recover the index.html file from the snapshot.

You can restore the index.html file from the snapshot as follows:

$ sudo cp -v /data/.snapshots/web1-2020-12-25/index.html /data/projects/web1/index.html

As you can see, the index.html file is restored from the snapshot.

$ cat /data/projects/web1/index.html
$ cat /data/.snapshots/web1-2020-12-25/index.html

Now, let’s see how to recover all the files/directories from the snapshot.

Remove all the files from the /data/projects/web1 snapshot as follows:

$ sudo rm -rv /data/projects/web1/*

To recover all the files/directories from the snapshot, run the following command:

$ sudo rsync -avz /data/.snapshots/web1-2020-12-25/ /data/projects/web1/

As you can see, the files/directories are restored from the snapshot.

$ ls -lh /data/projects/web1

Finally, let’s see how to recover files/directories from the snapshot in mirror mode. In mirror mode, the subvolume’s files/directories will be the same as in the snapshot. If there are any files/directories in the subvolume that are not available in the snapshot, they will be removed.

Let’s create a new file in the subvolume to differentiate the file tree from the snapshot.

Create a README.txt file in the /data/projects/web1 subvolume as follows:

$ echo "hello world 5" | sudo tee /data/projects/web1/README.txt

As you can see, the file tree of the /data/projects/web1 subvolume is different from the /data/.snapshots/web1-2020-12-25 snapshot.

$ tree -a /data

To restore the files/directories from the /data/.snapshots/web1-2020-12-25 snapshot to the /data/projects/web1 subvolume in mirror mode, run the following command:

$ sudo rsync -avz --delete /data/.snapshots/web1-2020-12-25/ /data/projects/web1/

All the files/directories of the /data/projects/web1 subvolume should be restored (in mirror mode) from the /data/.snapshots/web1-2020-12-25 snapshot.

The file tree of the /data/projects/web1 subvolume and the /data/.snapshots/web1-2020-12-25 snapshot should be the same.

As you can see, the index.html file and style.css file contents are the same in the /data/projects/web1 subvolume and the /data/.snapshots/web1-2020-12-25 snapshot.

Contents of the index.html and style.css file in the /data/projects/web1 subvolume.

$ cat /data/projects/web1/index.html
$ cat /data/projects/web1/style.css

Contents of the index.html and style.css file in the /data/.snapshots/web1-2020-12-25 snapshot.

$ cat /data/projects/web1/index.html
$ cat /data/projects/web1/style.css

Updating a Snapshot

By default, the Btrfs filesystem takes writable snapshots. A Btrfs snapshot is just like a subvolume. So, you can modify/update the files/directories of a writable snapshot.

Let’s update the index.html file in the /data/projects/web1 subvolume.

First, open the index.html file from the /data/projects/web1 subvolume with the nano text editor as follows:

$ sudo nano /data/projects/web1/index.html

Make any changes you want. Once you’re done, press <Ctrl> + X followed by Y and <Enter> to save the index.html file.

As you can see, the index.html file of the /data/projects/web1 subvolume is different from the /data/.snapshots/web1-2020-12-25 snapshot.

$ cat /data/projects/web1/index.html
$ cat /data/.snapshots/web1-2020-12-25/index.html

You want to keep the index.html file of the /data/projects/web1 subvolume.

To update the index.html file in the /data/.snapshots/web1-2020-12-25 snapshot, run the following command:

$ sudo cp -v /data/projects/web1/index.html /data/.snapshots/web1-2020-12-25/index.html

As you can see, the index.html file of the /data/.snapshots/web1-2020-12-25 snapshot is updated.

Updating a snapshot is as easy as copying new files to the snapshot.

Taking Read-Only Snapshots of a Subvolume

At times, you don’t want the snapshots you’ve taken to be updated in any way. In that case, you can create read-only snapshots.

For example, to create a read-only snapshot /data/.snapshots/web1-2020-12-26 of the /data/projects/web1 subvolume, run the following command:

$ sudo btrfs subvolume snapshot -r /data/projects/web1 /data/.snapshots/web1-2020-12-26

As you can see, a new subvolume .snapshots/web1-2020-12-26 is created.

$ sudo btrfs subvolume list /data

As you can see, the snapshot /data/.snapshots/web1-2020-12-26 is read-only.

$ sudo btrfs subvolume show /data/.snapshots/web1-2020-12-26

Let’s update the index.html file from the /data/projects/web1 subvolume.

To do that, open the index.html file from the /data/projects/web1 subvolume with the nano text editor as follows:

$ sudo nano /data/projects/web1/index.html

Make any changes you want. Once you’re done, press <Ctrl> + X followed by Y and <Enter> to save the changes.

As you can see, the index.html in the /data/projects/web1 subvolume is different from the /data/.snapshots/web1-2020-12-26 snapshot.

$ cat /data/projects/web1/index.html
$ cat /data/.snapshots/web1-2020-12-26/index.html

Let’s try to update the index.html file in the /data/.snapshots/web1-2020-12-26 snapshot.

$ sudo cp -v /data/projects/web1/index.html /data/.snapshots/web1-2020-12-26/index.html

As you can see, you can’t update the index.html file of the /data/.snapshots/web1-2020-12-26 snapshot because the snapshot is read-only.

Removing a Snapshot

I have told you earlier that a Btrfs snapshot is like a subvolume. So, you can remove a Btrfs snapshot just like you remove a Btrfs subvolume. Same command.

This is how the file tree of the Btrfs filesystem mounted on the /data directory looks like at the moment.

$ tree -a /data

Let’s remove the .snapshots/web1-2020-12-25 snapshot.

$ sudo btrfs subvolume list /data

To remove the /data/.snapshots/web1-2020-12-25 snapshot, run the following command:

$ sudo btrfs subvolume delete /data/.snapshots/web1-2020-12-25

As you can see, the snapshot .snapshots/web1-2020-12-25 is no more.

$ sudo btrfs subvolume list /data

As you can see, the files/directories of the /data/.snapshots/web1-2020-12-25 snapshot is removed as well.

$ tree -a /data

Conclusion

This article has shown you how to take writable and read-only snapshots of your Btrfs filesystem subvolumes. I have also shown you how to update a writable snapshot and recover files from a snapshot. I have shown you how to remove a Btrfs snapshot as well. This article should help you get started with the Btrfs snapshot feature.

About the author

Shahriar Shovon

Shahriar Shovon

Freelancer & Linux System Administrator. Also loves Web API development with Node.js and JavaScript. I was born in Bangladesh. I am currently studying Electronics and Communication Engineering at Khulna University of Engineering & Technology (KUET), one of the demanding public engineering universities of Bangladesh.