I am on macOS and I use Time Machine for backups. My goal is to make sure that if I lose my machine, I can get a new one and restore from backup as fast as possible – ideally without having to do anything manually. This is why I am reluctant to exclude anything from backups, even data that is available publicly and could be easily redownloaded.
However, my /nix/store is huge – and it slows down the backup process enough that I would be glad to exclude it. My question is: is it safe to do?
In other words, let’s say I rm -rf /nix/store from my machine, leaving everything else intact. Will Nix detect that paths are missing and redownload them automatically during nix-build? Is there a database file somewhere in /nix that will have to be rebuilt? Will something break insidiously due to hard-linking done by nix-store --optimize? Etc.
There is /nix/var/nix/db, which contains refs to /nix/store. It may be used to restore content of store. For example, let’s remove some store path hard way (I’m doing it on NixOS, hence I have to fight with RO filesystem):
$ mkdir /tmp/nix-store
$ sudo mount --bind /nix/store/ /tmp/nix-store
$ sudo mount --bind -o rw,remount /nix/store/ /tmp/nix-store
$ sudo rm -rf /tmp/nix-store/zmd03lv31gg4n92bwznkhsz9fy13xprs-go-1.12.1
$ nix-store --verify
reading the Nix store...
checking path existence...
path '/nix/store/zmd03lv31gg4n92bwznkhsz9fy13xprs-go-1.12.1' disappeared, but it still has valid referrers!
warning: not all errors were fixed
This particular store path is present in Nix global cache, so we can redownload it easily with an operation called --repair:
$ sudo nix-store --verify --repair
reading the Nix store...
checking path existence...
path '/nix/store/zmd03lv31gg4n92bwznkhsz9fy13xprs-go-1.12.1' disappeared, but it still has valid referrers!
copying path '/nix/store/zmd03lv31gg4n92bwznkhsz9fy13xprs-go-1.12.1' from 'https://cache.nixos.org'...
$
But there are store paths which are impossible to fetch from Nix global cache. The obvious first example is ~/.nix-profile reference. It is a link to /nix/store, which is known only on your local machine. So this won’t be fixed using nix-store --verify --repair.
Answering your question – nix-build will fail because /nix/store is corrupted. It won’t fail if you clear-up your Nix sqlite DB (reinstall Nix from scratch, for example). But then you loose list of your stuff installed with nix-env. Though if you use nix-shells everywhere, this shouldn’t be a problem.
The restore process will be more of a pain, but as long as none of your Nix caches goes down, and any urls you make Nix download in your config remain up, it should at least be fully reproducible.
I consider it “safe enough” that I do omit it myself. The main things that you lose by excluding it are:
Profiles — that means if you restore a backup you will not be able to roll back to profile/system generations from before the backup;
The store paths themselves, which may be expensive to build or download;
User environments managed in a completely imperative way.
In my case, the first is worth the space savings, the second isn’t the case (my internet is fast enough that it’s reasonable to download everything again and I don’t have anything that requires a lot of building), and I manage my user profiles declaratively so the third doesn’t bother me.