In rare cases you might want to delete files from snapshots. Normally you shouldn’t, but this is how you do it.
If you rely on BTRFS snapshots you might sometimes find yourself in the situation where you have accidentally created a handful of very large files with the intention to remove them very soon. You get distracted, and suddenly a couple of days have passed and your temporary dinosaur files have been snapshotted and it is no longer easy to reclaim the disk space.
At one customer we were slowly running out of disk space on a Synology volume, and we discovered two things:
- We had a
./Tempdirectory in a share where we allow people to store temporary files. This directory had some backup files laying around that were quite large.
- The share also had the
#recyclebin enabled on the Synology, and we had not emptied in a while
The sysadmin who had used the
./Temp directory usually deleted the files after himself, but did not know that we have the
#recycle enabled. So for him it was natural to just ignore that aspect of the dilemma. Every now and then, he had also not deleted the .BAK files right away, waiting for a day or two in case we would need the files.
Both these locations (the
./Temp, and the
#recycle) are parts of the nightly snapshots, and are therefore difficult to get rid of. And getting rid of them we really wanted, as we were slowly running out of diskspace. Part of this problem is that we use snapshots for that very reason that if we accidentally delete a file or overwrite it by mistake, we will be able to restore it from a previous snapshot. The whole idea with snapshots is that the files should be difficult to remove.
Cleanup tainted btrfs snapshots
To reclaim the diskspace from files that are snapshotted, we need to get rid of each and every incarnation of the file from the main filesystem as well as from the snapshots. From the filesystem itself it is easy to delete the files. Just
rm the file, and you are done. But from the snapshots, you need to dig a bit deeper.
There is a good tool to figure out the size of snapshots,
btrfs-du, see https://github.com/nachoparker/btrfs-du. It is a bit outside the scope of this post, but useful.
The snapshots are found in the
/volumeX/@sharesnap/YOUR_SHARE directory. To delete the files you want to get rid of, you need to:
- Set the snapshots to “ro false” (i.e you make the snapshots read/write:able)
- Remove unwanted files from the snapshots
- Set the snapshots to “ro true”
Since I like to be able to check the command sequence before I execute them, I first create a temporary script file
/tmp/a, which does the dirty work for me.
#--- make the snapshots writable ls /volume1/@sharesnap/X/ | grep GMT | xargs -L1 -IX echo sudo btrfs property set X ro false > /tmp/a . /tmp/a #--- delete files ls -la /volume1/@sharesnap/X/*/\#recycle/SomewhereWithLargeFiles/Temp/MyUser/*.BAK readlink -f /volume1/@sharesnap/X/*/\#recycle/SomewhereWithLargeFiles/Temp/MyUser/*.BAK | xargs -L1 -IX echo sudo rm X | tee /tmp/b #--- don't forget to read through /tmp/b before running it . /tmp/b #--- make the snapshots read only ls /volume1/@sharesnap/X/ | grep GMT | xargs -L1 -IX echo sudo btrfs property set X ro true > /tmp/c . /tmp/c #--- examples sudo btrfs property set GMT+02-2022.10.27-00.00.03 ro true sudo btrfs property set GMT+02-2022.10.28-00.00.03 ro true sudo btrfs property set GMT+02-2022.10.29-00.00.02 ro true sudo btrfs property set GMT+02-2022.10.30-00.00.03 ro true sudo btrfs property set GMT+02-2022.10.27-00.00.03 ro false sudo btrfs property set GMT+02-2022.10.28-00.00.03 ro false sudo btrfs property set GMT+02-2022.10.29-00.00.02 ro false sudo btrfs property set GMT+02-2022.10.30-00.00.03 ro false
In this particular situation, we reclaimed ca 1.5TB out of 4.7TB assigned diskspace. It is a bit cumbersome to clean up the snapshots like this, but well worth the effort.
- https://github.com/nachoparker/btrfs-du/blob/master/btrfs-du https://web.archive.org/web/20220510050424/https://ownyourbits.com/2017/12/06/check-disk-space-of-your-btrfs-snapshots-with-btrfs-du/ (some explanations to above script)