lix/src
raito 2a7a6cb85a fix(local-store): invalidate phantom referrers at garbage collection time
Sometimes, a path can disappear from the `ValidPaths` table (I have 23
such cases on my 1.4TB Nix store).

When this occurs and you try to run a garbage collection,
`queryReferrers` will report no referrer because it's performing a
*RIGHT JOIN* between `Refs` and `ValidPaths`, finally, when you issue
the deletion SQL statement, this will throw an uncaught exception from
SQLite side regarding a foreign key violation because `reference` in
`Refs` is a foreign key to `ValidPaths` (which we are trying to delete).

Why can this happen?

Two reasons:

* `PRAGMA foreign_keys=off;` will disable deletion on cascade.
* Trigger recursion *limits*, a deletion on cascade is a *trigger*, when
  a delete is issued and it triggers a bunch of deletion on cascade,
  there's a documented limit by SQLite: https://www.sqlite.org/limits.html#max_trigger_depth

  > Recursion limit on foreign key actions. The SQLITE_MAX_TRIGGER_DEPTH
  > and SQLITE_LIMIT_TRIGGER_DEPTH settings determine the maximum
  > allowable depth of trigger program recursion. For the purposes of
  > these limits, foreign key actions are considered trigger programs. The
  > PRAGMA recursive_triggers setting does not affect the operation of
  > foreign key actions. It is not possible to disable recursive foreign
  > key actions.

As I do not see easy ways to solve the root cause, garbage collection
should be self-healing in that regards, so I propose to invalidate
phantom referrers as we go.

As part of a work improving the consistency of the SQLite database, it
would make sense to count how many times this happen and try to find
ways to reproduce this issue.

Change-Id: I055a8a1d8c0e44d4388a411abe8e5a5e385f7b55
Signed-off-by: Raito Bezarius <raito@lix.systems>
2024-09-14 20:09:17 +02:00
..
asan-options tree-wide: add support for asan! 2024-07-31 14:13:39 -07:00
build-remote tree-wide: shuffle headers around for about 30s compile time 2024-08-28 09:55:05 -07:00
libcmd tree-wide: shuffle headers around for about 30s compile time 2024-08-28 09:55:05 -07:00
libexpr repl-overlays: Provide an elaborate example 2024-09-01 15:30:58 -07:00
libfetchers libfetchers: serialise accept-flake-config properly 2024-09-02 18:50:15 +02:00
libmain fish-completion: leave the shell prompt intact 2024-09-11 19:03:11 +02:00
libstore fix(local-store): invalidate phantom referrers at garbage collection time 2024-09-14 20:09:17 +02:00
libutil Merge "Add getCwd" into main 2024-09-10 00:10:40 +00:00
lix-doc rowan: 0.15.15 -> 0.15.16 2024-08-26 11:34:43 -07:00
nix Merge "Stop the logger in legacy commands again" into main 2024-09-06 17:07:16 +00:00
nix-build tree-wide: unify progress bar inactive and paused states 2024-07-01 18:19:34 +02:00
nix-channel util.{hh,cc}: Split out users.{hh,cc} 2024-05-29 11:01:34 +02:00
nix-collect-garbage Fix dry-run flag for nix-collect-garbage 2024-07-09 13:55:05 +00:00
nix-copy-closure Merge pull request #9277 from keszybz/file-permissions 2024-03-04 05:26:17 +01:00
nix-env fix: check if it is a Real terminal, not just if it is a terminal 2024-08-10 16:07:21 -07:00
nix-instantiate libexpr: pass Exprs as references, not pointers 2024-06-17 19:46:44 +00:00
nix-store tree-wide: shuffle headers around for about 30s compile time 2024-08-28 09:55:05 -07:00
pch tree-wide: shuffle headers around for about 30s compile time 2024-08-28 09:55:05 -07:00
lix-base.pc.in packaging: rename nixexpr -> lixexpr and so on 2024-05-23 16:45:23 -06:00
meson.build lix-doc: move under src/ 2024-08-20 13:38:46 -06:00