Documentation
Source: https://btrfs.readthedocs.io/en/latest/index.html
Copy on Write
Btrfs is a filesystem using the Copy on Write mechanism. This makes many other features of btrfs possible.
Copy on Write basically optimizes the usage of copies of data. If the system accesses data and / or creates a copy of it this data will not be written again at a given location. Only if an actually change is applied to the copied data a write command is executed. Thus, copies of data are at first only links to the old location. Only upon change of the data it will be written.
This is useful for the snapshots feature of Btrfs subvolumes, since those snapshots do not take up much space as they are only links to existing data. Those snapshots can even be configured to be read-only. In this case they will always point to the original data and can be used for backup purposes, i.e. export the snapshot data to external storage.
Snapshots
Source: https://fedoramagazine.org/btrfs-snapshots-backup-incremental/
Cheatsheet
Make subvolume read-only
btrfs property set -ts /path/to/snapshot ro true
Create snapshot
sudo btrfs subvolume snapshot -r <path_to_target_folder> <path_to_target_folder>/@<snapshot_name>
List all available snapshots:
sudo btrfs subvolume list <path_to_snapshot_location>
However, if the snapshot was created using the above command without a special subvolume mount also the standard ls
command will work and show the snapshot.
Send / Receive a snapshot
btrfs send /home/.snapshots/23/snapshot | pv | btrfs receive /mnt/BACKUP/23
btrfs send -p /mnt/data/old_snaphot /mnt/data/new_snaphot | ssh root@ip "btrfs receive /mnt/backups"
Make a already exiting folder to a subvolume
It is not possible to make a normal folder a btrfs subvolume unfortunately. But there is a more or less easy way around that. First create a temporary folder that holds the data of the folder that should be changed to a subvolume:
mv <path_to_target_folder> <path_to_temp_folder>
Now create a subvolume at the spot where the target folder was before:
btrfs sub create <path_to_target_folder>
Now use btrfs reflinks based on Copy on Write to do an instant copy of the data. This basically creates a link to the datas position while keeping the existing links independent - unlike with a hardlink, where changes of the data through one link would also change the data accessible through Al other hardlinks.
cp -aT --reflink=always <path_to_temp_folder> <path_to_target_folder>
Delete the tmeporary folder
rm -r <path_to_temp_folder>
btrbk
Source:
The tool btrbk is an easy way to automate snapshots and backups with Btrfs. Setting this tool up for offsite backups via SSH is also very easy, since the target server address, the SSH user and the SSH key can be defined it the corresponding btrbk configuration file.
Btrbk itself is a tool consisting of just one file. For every backup job a configuration file has to be created that defines
- the target to backup to,
- the disk that should be backupped,
- all subvolumes from the disk that should be backupped,
- the backup retention information and
- several optional parameters. A minimal setup however is easy to set up.
Upon setup of the tool just make sure that perl, wget and buffer are installed. To set it up create a new folder for the btrbk base script. For instance at /etc/btrbk/
.
Then run the following commands:
wget https://raw.githubusercontent.com/digint/btrbk/master/btrbk
chmod +x btrbk
sudo ./btrbk ls /
When you have set up a configuration file you can dry-run it to see if the output is as expected and of no errors occur. Make sure that you are in the btrbk folder you set up earlier. The option -n
in this case declares the dry-run.
./btrbk -c /path/to/myconfig -v -n run
With the option --progress
progress information will be displayed during the backup. This however only works if mbuffer was installed beforehand.
Here is an example btrbk configuration file where a local machine will backup the specified subvolumes to an external machine via SSH:
#
# Example btrbk configuration file
#
#
# Please refer to the btrbk.conf(5) man-page for a complete
# description of all configuration options.
# For more examples, see README.md included with this package.
#
# btrbk.conf(5): <https://digint.ch/btrbk/doc/btrbk.conf.5.html>
# README.md: <https://digint.ch/btrbk/doc/readme.html>
#
# Note that the options can be overridden per volume/subvolume/target
# in the corresponding sections.
#
# Enable transaction log
transaction_log /var/log/btrbk.log
# Specify SSH private key for remote connections
ssh_identity /root/.ssh/id_rsa
ssh_user root
# Enable stream buffer. Adding a buffer between the sending and
# receiving side is generally a good idea.
# NOTE: If enabled, make sure to install the "mbuffer" package!
stream_buffer 256m
#
# Example retention policy:
#
snapshot_preserve_min 2d
snapshot_preserve 14d
target_preserve_min no
target_preserve 20d 10w *m
#
# Simple setup: Backup root and home to external disk
#
# the snapshot directory is prefereably not inside the folder
# that shall be backed up.
snapshot_dir <snapshot_directory>
target ssh://<ip_of_target_machine>:<ssh_port><target_directory>
subvolume <first_target_subvolume>
subvolume <second_target_subvolume>
subvolume <third_target_subvolume>