Nix `nix-collect-garbage` 命令完全指南:安全清理 Nix Store 与旧 profile 代际

发布时间:2026/9/21 15:48:19
Nix `nix-collect-garbage` 命令完全指南:安全清理 Nix Store 与旧 profile 代际 开发工具CLI【免费下载链接】nixNix, the purely functional package manager项目地址https://gitcode.com/gh_mirrors/ni/nix点击查看免费下载nix-collect-garbage是 Nix纯函数式包管理器中用于清理 Nix Store 的便捷工具它在nix-store --gc的垃圾回收能力之上额外提供了删除旧 profile 代际generation的能力从而释放更多磁盘空间。本文以官方命令参考文档为主体结合本仓库中该命令的 C 实现源码src/nix/nix-collect-garbage/nix-collect-garbage.cc与 profile 代际管理实现src/libstore/profiles.cc系统讲解其工作原理、全部选项、profile 搜索范围、等价命令关系及底层 GC 机制帮助你安全、高效地完成系统清理。命令概览nix-collect-garbage的完整语法如下nix-collect-garbage [--delete-old] [-d] [--delete-older-than period] [--max-freed bytes] [--dry-run]从功能上看该命令大部分是nix-store --gc的别名——它同样会删除 Nix Store 中所有不可达unreachable的 store object即 store 路径从而清理系统。所谓不可达指的是无法通过一组被称为GC roots垃圾回收根的引用从文件系统层面触及的 store 对象而可达的对象live永远不会被删除否则会破坏系统一致性——已安装的应用可能引用 store 中已不存在的内容。与nix-store --gc的关键区别在于nix-collect-garbage额外提供了两个选项--delete-old与--delete-older-than它们会先删除旧 profile 代际再进行垃圾回收。由于 profile 本身也是垃圾回收根删掉旧代际后原本被它们引用的 store 对象将变为不可达从而允许 GC 删除更多内容。与nix-env --delete-generations的等价关系--delete-old与--delete-older-than两个选项本质上等价于先在多个 profile 上执行nix-env --delete-generations的各类参数然后再执行不带任何标志的nix-collect-garbage或直接nix-store --gcnix-collect-garbage选项等价操作--delete-old/-d对每个找到的 profile 执行nix-env --delete-generations old--delete-older-than period对每个找到的 profile 执行nix-env --delete-generations period其中old表示删除除当前代际之外的所有代际。注意由于可以回滚到之前的代际比当前代际更新的代际同样会被删除这正是 delete-generations.md 中明确警告过的行为。period形如30d表示删除创建时间早于 30 天的所有代际但保留在那个时间点处于活动状态的那一代以便仍可回滚到该时间段内的状态。重要警告官方文档明确提示了两点务必在使用前理解删除旧代际会使回滚到这些时间点变得不可能。代际是回滚的载体一旦删除就无法恢复。这些标志应谨慎使用因为它们可能删除系统上其他用户所使用的 profile 代际——nix-collect-garbage会跨多个用户目录搜索 profile详见下文并非只针对当前用户。搜索 profile 的位置nix-collect-garbage无法获知系统上所有的 profile该信息并不存在它只会在若干固定位置查找并处理找到的所有 profile默认 profile 位置由 profiles 文档 规定即普通用户$XDG_STATE_HOME/nix/profilesroot用户$NIX_STATE_DIR/profiles/per-user/root已废弃的旧版路径官方标注Not stable; subject to change仅供迁移用途属 Nix 私有实现细节未来可能变更不应依赖$NIX_STATE_DIR/profiles$NIX_STATE_DIR/profiles/per-user除$NIX_STATE_DIR/profiles/per-user/root和$NIX_STATE_DIR/profiles/default外这些目录已不再被其他命令使用。nix-collect-garbage仍会检查它们目的是清理旧版本 Nix 遗留的 profile。在源码层面这一逻辑体现在 nix-collect-garbage.cc 的main_nix_collect_garbage中当指定了删除旧代际的标志时程序构造一个待清理目录集合dirsToClean包含profilesDir(profilesDirOpts)默认 profile 根目录、settings.nixStateDir / profiles以及默认 profile 的父目录getDefaultProfile(profilesDirOpts).parent_path()然后对每个目录递归调用removeOldGenerations(dir)。removeOldGenerations的实现细节值得注意若目录不可读access(..., R_OK)失败则直接跳过递归遍历子目录对符号链接且目录可写W_OK的条目读取其链接目标只有当目标路径中包含子串link时才视为 profile 代际链接并处理对应profile-N-link命名约定若指定了--delete-older-than则调用deleteGenerationsOlderThan(path, t, dryRun)否则调用deleteOldGenerations(path, dryRun)每次遍历迭代都会调用checkInterrupt()以便在收到中断信号时安全退出。profile 的文件系统布局节选自 profiles.md形如profile是指向profile-N-link的符号链接而profile-N-link又是指向 store 中某路径的符号链接。每个这样的符号链接都是 Nix 垃圾收集器的一个根因此删除代际链接会直接改变 GC 的可达性判定。选项详解以下选项用于在删除不可达 store 对象之前删除旧 profile 代际。--delete-old/-d删除所有找到的 profile 的旧代际即除当前代际外的所有代际。等价于对每个找到的 profile 调用nix-env --delete-generations old。在源码中解析到--delete-old或-d时置位removeOld true。--delete-older-thanperiod删除早于指定时间的所有 profile 代际但保留在那一时间点处于活动状态的代际。period是诸如30d这样的值表示 30 天。等价于对每个找到的 profile 调用nix-env --delete-generations periodperiod 参数的更多细节可参考 delete-generations.md。从源码看period 的解析由 profiles.cc 中的parseOlderThanTimeSpec完成以d结尾否则报错invalid number of days specifier提示应类似14d前部必须是合法的正整数天数days 1返回当前时间 - days * 24 * 3600秒级时间戳。随后deleteGenerationsOlderThan按代际创建时间lstat得到的st_mtime见findGenerations从新到旧扫描找到第一个早于目标时间的代际后保留其前一代即那个时间点活跃的代际以便回滚再删除其余所有更早的代际当前代际除外。findGenerations通过解析profile名-数字-link的命名模式来识别代际编号。--max-freedbytes持续删除路径直到至少释放bytes字节后停止。bytes可附带乘法后缀K、M、G或T分别表示 KiB、MiB、GiB、TiB。该选项直接透传给底层 GC 的GCOptions.maxFreed字段默认值为UINT64_MAX即不设上限由 gc-store.hh 中的GCOptions结构承载。源码中通过getIntArgint64_t解析并以std::max(..., 0)保证非负。--dry-run只报告将要删除的内容而不真正删除。其行为在源码中体现为底层 GC 动作由gcDeleteDead实际删除切换为gcReturnDead仅返回死路径集合结果仍通过printFreed打印将释放的字节数profile 代际删除走deleteGeneration2的 dry-run 分支仅打印would remove profile version Nprofiles.cc。注意--dry-run与--max-freed不能同时使用——源码中两者同时出现时会抛出UsageError(options --max-freed and --dry-run cannot be combined)。公共选项与环境变量与大多数 Nix 命令一样该命令还接受 公共选项--help、--version、-v/--verbose、--quiet、--log-format、--option等与 公共环境变量。与本文主题直接相关的环境变量包括NIX_STATE_DIR覆盖 Nix 状态目录位置影响$NIX_STATE_DIR/profiles等搜索路径的解析NIX_STORE_DIR覆盖 Nix Store 的位置NIX_REMOTE覆盖store配置决定 GC 作用于哪个 store。底层 GC 流程nix-collect-garbage在完成代际清理后会打开默认 storeopenStore()通过requireGcStore要求其支持垃圾回收然后执行gcStore.collectGarbage(options, results)。相关类型定义在 gc-store.hhGCAction枚举gcReturnLive返回从根可达的路径闭包、gcReturnDead返回不可达路径、gcDeleteDead实际删除不可达路径默认动作、gcDeleteSpecific仅删除指定列表中的不可达路径GCOptions包含action、maxFreed、pathsToDelete整店删除WholeStore或指定路径SpecificPaths、ignoreLiveness等GCResults返回删除的路径集合与释放的字节数bytesFreed。nix-collect-garbage始终以WholeStore整店方式执行并配合--max-freed控制停止时机。回收器完成或被中断时会打印释放的总字节数例如8825586 bytes freed (8.42 MiB)见 gc.md 示例。此外GC 行为还受 Nix 配置文件中的keep-outputs默认false与keep-derivations默认true两个设置影响详见 垃圾回收指南默认值保证所有作为 GC 根构建时依赖的 derivation 会被保留所有作为运行时依赖的 output 也会被保留其余内容才会被回收。使用示例删除 Nix Store 中不被各 profile 当前代际使用的所有内容并同时清理所有旧代际$ nix-collect-garbage -d这是官方文档给出的一键清理标准做法-d先在各 profile 上等效执行nix-env --delete-generations old随后执行完整 GC。其他常见用法# 仅清理 30 天前的旧代际 完整 GC $ nix-collect-garbage --delete-older-than 30d # 限制本次 GC 最多只释放约 100 MiB $ nix-collect-garbage --max-freed $((100 * 1024 * 1024)) # 先演练一遍看看会删除什么 $ nix-collect-garbage --dry-run延伸更细粒度的控制若需要比nix-collect-garbage更细的控制可直接使用其底层命令nix-store --gc提供--print-roots打印 GC 根、--print-live打印可达路径、--print-dead打印将删除的路径子操作以及--max-freed选项nix-env --delete-generations支持按代际编号列表如3 4 8、old、numberd按天数与number保留最近 N 代等多种方式精确管理单个 profile 的代际需要彻底回收空间时可配合nix-store --optimise进行 store 内的硬链接去重或参考 垃圾回收指南 中的完整清理流程先删旧代际、再执行 GC。建议将nix-collect-garbage -d或--delete-older-than 30d纳入定期维护任务如 cron / systemd timer以避免 store 无限膨胀对于多用户共享机器优先使用--delete-older-than而非--delete-old以减少误删他人可用代际的风险。赞分享开发工具CLI【免费下载链接】nixNix, the purely functional package manager项目地址https://gitcode.com/gh_mirrors/ni/nix点击查看免费下载相关推荐nixpkgs构建缓存清理nix-collect-garbage使用指南nixpkgs构建缓存清理nix collect garbage使用指南 你是否遇到过NixOS系统磁盘空间持续增长的问题随着软件包的频繁更新和构建系统会包管理器操作系统NixOS/nix项目深入解析nix-store --query命令完全指南NixOS/nix项目深入解析nix store query命令完全指南 引言为什么需要深入了解nix store query 你是否曾经在使用Nix包管开发工具CLINix nix-store --realise 命令完全指南构建与获取 store objects 的核心机制Nix nix store realise 命令完全指南构建与获取 store objects 的核心机制 本指南以 Nix 官方手册中 nix store开发工具CLI上一篇终结重复代码Awesome Claude Code资源覆盖机制终极指南下一篇2025 Rust算法调试指南从零配置VS Code完美开发环境创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考