A while ago I switched backups from Duplicity to Restic. About time: I was using Duplicity for many years (I think I started using it around 2010, long before Restic became available) and it served me well. But recently I ran into more and more issues, especially with archives getting larger and larger. There is an 11 years old open bug in the Duplicity bugtracker, which describes a showstopper for backing up larger archives. And it doesn’t look like this will be solved anytime soon. Therefore it was time for something new.
Since I’m rolling out my backups with Ansible, it was relatively easy to create a set of scripts for Restic which use almost the same infrastructure as the old Duplicity backups. That works as expected on all our laptops. But the Raspberry Pi, which does the fileserver backups, seem to had a problem. Backups took way longer than before, jumped from 30-60 minutes (depending on the amount of changes) to constantly around 10 hours.
After some investigation (means:
--verbose --verbose --verbose debugging), it turns out that Restic identifies most of the files as new, even though they did not change at all. Some background information: the Raspberry mounts the QNAP fileserver using the SMB3 protocol. The
mount -t cifs uses the
serverino option, but apparently that is not enough to provide a stable inode number. And if the inode for a file changes, Restic assumes it is a new file.
On the bright side, because the content of the files do not change, the deduplication still works, and no additional content is added to the backup. The size of the backup does not increase. Still, Restic fetches all the data from the server, and that takes a long time.
I had to choose between updating everything to Testing (Bullseye), or figure out how to upgrade just one package.
The first step was checking the dependencies for the Restic package. The Restic in Bullseye depends only on
libc6 (>= 2.4), and Buster already has libc6 in version 2.28. So that will work. The Bullseye version also suggests the packages
libjs-underscore, but does not add any versions - any installed version should do. Both packages are available in Buster. On the dependency side nothing is blocking a single package upgrade.
Debian is using a mechanism called pinning to specify which version can be installed from which source. By default, everything comes from the packages repository, and everything has the same priority. But this can be changed, by adding files to
/etc/apt/preferences.d/. Using my Ansible Playbook (I install the Raspberry using Ansible), I did the following:
apt-pinning.txt file has the following content:
# 500 <= P < 990: causes a version to be installed unless there is a # version available belonging to the target release or the installed # version is more recent Package: * Pin: release a=stable Pin-Priority: 900 # 100 <= P < 500: causes a version to be installed unless there is a # version available belonging to some other distribution or the installed # version is more recent Package: * Pin: release a=testing Pin-Priority: 400 Package: restic Pin: release a=testing Pin-Priority: 900
stable packages become a
900 priority, and
testing packages a
400 priority. Only the
restic package in
testing has a
In order to use
testing packages, Debian also needs to know where to get these packages from:
An updated source list is installed, and when either the pinning file or the source list file changes, Ansible will update the apt cache. The source list file:
deb http://archive.raspberrypi.org/debian/ buster main # Uncomment line below then 'apt-get update' to enable 'apt-get source' #deb-src http://archive.raspberrypi.org/debian/ buster main deb http://raspbian.raspberrypi.org/raspbian/ bullseye main # Uncomment line below then 'apt-get update' to enable 'apt-get source' #deb-src http://raspbian.raspberrypi.org/raspbian/ bullseye main
So far, so good. Last step: install the package from testing. Ansible allows to specify which release should be used for a package:
After the Playbook ran, a quick version check shows:
The runtime for the backup is now 30-45 minutes. That’s expected.