Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update 11-garbage-collector.md #241

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions pills/11-garbage-collector.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Today, we will stop focusing on packaging and instead look at a critical compone

Programming languages with garbage collectors use the concept of a set of "garbage collector (or 'GC') roots" to keep track of "live" objects. A GC root is an object that is always considered "live" (unless explicitly removed as GC root). The garbage collection process starts from the GC roots and proceeds by recursively marking object references as "live". All other objects can be collected and deleted.

Instead of objects, Nix's garbage collection operates on store paths, [with the GC roots themselves being store paths](https://nixos.org/manual/nix/stable/package-management/garbage-collector-roots.html). . This approach is much more principled than traditional package managers such as `dpkg` or `rpm`, which may leave around unused packages or dangling files.
Instead of objects, Nix's garbage collection operates on store paths, [with the GC roots themselves being store paths](https://nixos.org/manual/nix/stable/package-management/garbage-collector-roots.html). This approach is much more principled than traditional package managers such as `dpkg` or `rpm`, which may leave around unused packages or dangling files.

The implementation is very simple and transparent to the user. The primary GC roots are stored under `/nix/var/nix/gcroots`. If there is a symlink to a store path, then the linked store path is a GC root.

Expand Down Expand Up @@ -60,7 +60,7 @@ The old generation is still in the nix store because it is a GC root. As we will
Removing a GC root is simple. In our case, we delete the generation that refers to `bsd-games`, run the garbage collector, and note that `bsd-games` is no longer in the nix store:

```console
$ rm /nix/var/nix/profiles/default-9-link
$ rm ~/.local/state/nix/profiles/default-9-link
$ nix-env --list-generations
[...]
8 2014-07-28 10:23:24
Expand All @@ -73,7 +73,9 @@ ls: cannot access /nix/store/b3lxx3d3ggxcggvjw5n0m1ya1gcrmbyn-bsd-games-2.17: No

Note: `nix-env --list-generations` does not rely on any particular metadata. It is able to list generations based solely on the file names under the profiles directory.

Note that we removed the link from `/nix/var/nix/profiles`, not from `/nix/var/nix/gcroots`. In addition to the latter, Nix treats `/nix/var/nix/profiles` as a GC root. This is useful because it means that any profile and its generations are GC roots. Other paths are considered GC roots as well; for example, `/run/booted-system` on NixOS. The command `nix-store --gc --print-roots` prints all paths considered as GC roots when running the garbage collector.
Note that we removed the link from `~/.local/state/nix/profiles`, not from `/nix/var/nix/gcroots`. When Nix creates a new profile, it also adds it as an "indirect GC root" to `/nix/var/nix/gcroots/auto` — see the next section!

Other paths are considered GC roots as well; for example, `/run/booted-system` on NixOS. The command `nix-store --gc --print-roots` prints all paths considered as GC roots when running the garbage collector.

## Indirect roots

Expand Down Expand Up @@ -113,7 +115,7 @@ Other systems typically "forget" everything about their previous state after an

- Then we upgrade our installed packages with `nix-env -u`. This will bring us into a new generation with updated software.

- Then we remove all the indirect roots generated by `nix-build`: beware, as this will result in dangling symlinks. A smarter strategy would also remove the target of those symlinks.
- Then we remove all the indirect roots generated by `nix-build`, by searching for targets named `result*`.

- Finally, the `-d` option of `nix-collect-garbage` is used to delete old generations of all profiles, then collect garbage. After this, you lose the ability to rollback to any previous generation. It is important to ensure the new generation is working well before running this command.

Expand All @@ -122,7 +124,7 @@ The four steps are shown below:
```console
$ nix-channel --update
$ nix-env -u --always
$ rm /nix/var/nix/gcroots/auto/*
$ for p in /nix/var/nix/gcroots/auto/*; do if [[ $(basename $(readlink $p)) == result* ]]; then echo $(readlink $p) && rm $(readlink $p) && rm $p; fi; done
$ nix-collect-garbage -d
```

Expand Down
Loading