raito
2a7a6cb85a
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:
|
||
---|---|---|
.. | ||
ca | ||
common | ||
config | ||
dyn-drv | ||
flakes | ||
lang | ||
nested-sandboxing | ||
plugins | ||
repl_characterization | ||
test-libstoreconsumer | ||
add.sh | ||
bad.tar.xz | ||
bash-profile.sh | ||
big-derivation-attr.nix | ||
binary-cache-build-remote.sh | ||
binary-cache.sh | ||
brotli.sh | ||
build-delete.sh | ||
build-dry.sh | ||
build-hook-ca-fixed.nix | ||
build-hook-ca-floating.nix | ||
build-hook.nix | ||
build-jobless.sh | ||
build-remote-content-addressed-fixed.sh | ||
build-remote-content-addressed-floating.sh | ||
build-remote-input-addressed.sh | ||
build-remote-trustless-after.sh | ||
build-remote-trustless-should-fail-0.sh | ||
build-remote-trustless-should-pass-0.sh | ||
build-remote-trustless-should-pass-1.sh | ||
build-remote-trustless-should-pass-2.sh | ||
build-remote-trustless-should-pass-3.sh | ||
build-remote-trustless.sh | ||
build-remote.sh | ||
build.sh | ||
ca-shell.nix | ||
case-hack.sh | ||
case.nar | ||
check-refs.nix | ||
check-refs.sh | ||
check-reqs.nix | ||
check-reqs.sh | ||
check.nix | ||
check.sh | ||
common.sh | ||
completions.sh | ||
compression-levels.sh | ||
compute-levels.sh | ||
config.nix.in | ||
config.sh | ||
db-migration.sh | ||
debugger.sh | ||
dependencies.builder0.sh | ||
dependencies.nix | ||
dependencies.sh | ||
derivation-json.sh | ||
dummy | ||
dump-db.sh | ||
eval-store.sh | ||
eval.nix | ||
eval.sh | ||
experimental-features.sh | ||
export-graph.nix | ||
export-graph.sh | ||
export.sh | ||
extra-sandbox-profile.nix | ||
extra-sandbox-profile.sh | ||
failing.nix | ||
fetchClosure.sh | ||
fetchers.sh | ||
fetchGit.sh | ||
fetchGitRefs.sh | ||
fetchGitSubmodules.sh | ||
fetchMercurial.sh | ||
fetchPath.sh | ||
fetchTree-file.sh | ||
fetchurl.sh | ||
filter-source.nix | ||
filter-source.sh | ||
fixed.builder1.sh | ||
fixed.builder2.sh | ||
fixed.nix | ||
fixed.sh | ||
fmt.sh | ||
fmt.simple.sh | ||
fod-failing.nix | ||
function-trace.sh | ||
gc-auto.sh | ||
gc-concurrent.builder.sh | ||
gc-concurrent.nix | ||
gc-concurrent.sh | ||
gc-concurrent2.builder.sh | ||
gc-non-blocking.sh | ||
gc-runtime.nix | ||
gc-runtime.sh | ||
gc.sh | ||
hash-check.nix | ||
hash.sh | ||
hermetic.nix | ||
ifd.nix | ||
import-derivation.nix | ||
import-derivation.sh | ||
impure-derivations.nix | ||
impure-derivations.sh | ||
impure-eval.sh | ||
init.sh | ||
install-darwin.sh | ||
lang-test-infra.sh | ||
lang.sh | ||
legacy-ssh-store.sh | ||
linux-sandbox-cert-test.nix | ||
linux-sandbox.sh | ||
local-store.sh | ||
logging.sh | ||
meson.build | ||
misc.sh | ||
multiple-outputs.nix | ||
multiple-outputs.sh | ||
nar-access.nix | ||
nar-access.sh | ||
nested-sandboxing.sh | ||
nix-build-examples.nix | ||
nix-build.sh | ||
nix-channel.sh | ||
nix-collect-garbage-d.sh | ||
nix-collect-garbage-dry-run.sh | ||
nix-copy-ssh-common.sh | ||
nix-copy-ssh-ng.sh | ||
nix-copy-ssh.sh | ||
nix-daemon-untrusting.sh | ||
nix-profile.sh | ||
nix-shell.sh | ||
nix_path.sh | ||
optimise-store.sh | ||
output-normalization.sh | ||
parallel.builder.sh | ||
parallel.nix | ||
parallel.sh | ||
pass-as-file.sh | ||
path-from-hash-part.sh | ||
path.nix | ||
phantom-referrers-gc.sh | ||
placeholders.sh | ||
plugins.sh | ||
post-hook.sh | ||
pure-eval.nix | ||
pure-eval.sh | ||
push-to-store-old.sh | ||
push-to-store.sh | ||
read-only-store.sh | ||
readfile-context.nix | ||
readfile-context.sh | ||
recursive.nix | ||
recursive.sh | ||
referrers.sh | ||
regression-484.sh | ||
remote-store.sh | ||
repair.sh | ||
repl.sh | ||
restricted.nix | ||
restricted.sh | ||
search.nix | ||
search.sh | ||
secure-drv-outputs.nix | ||
secure-drv-outputs.sh | ||
selfref-gc.sh | ||
shell-hello.nix | ||
shell.nix | ||
shell.sh | ||
shell.shebang.nix | ||
shell.shebang.rb | ||
shell.shebang.sh | ||
signing.sh | ||
simple-failing.nix | ||
simple.builder.sh | ||
simple.nix | ||
simple.sh | ||
ssh-relay.sh | ||
store-ping.sh | ||
structured-attrs-shell.nix | ||
structured-attrs.nix | ||
structured-attrs.sh | ||
substitute-truncated-nar.sh | ||
substitute-with-invalid-ca.sh | ||
suggestions.sh | ||
supplementary-groups.sh | ||
symlink-derivation.nix | ||
tarball.sh | ||
test-infra.sh | ||
test-libstoreconsumer.sh | ||
test-repl-characterization.sh | ||
timeout.nix | ||
timeout.sh | ||
toString-path.sh | ||
undefined-variable.nix | ||
user-envs-migration.sh | ||
user-envs.builder.sh | ||
user-envs.nix | ||
user-envs.sh | ||
why-depends.sh | ||
zstd.sh |