OFFSET偏移
← 文章目录OFFSET / FIELD NOTESNO. 018

NixOS 世代管理与垃圾回收

按查看、激活、删除历史和回收存储理解 generation 生命周期。

所在专题NixOS 系统基础与配置 ↗
约 10 分钟阅读开始阅读

NixOS 中管理 generation(系统世代)主要通过 nixos-rebuild、nix-env 和 nix-collect-garbage 三组命令完成,核心操作是查看、切换、删除、清理,配合 configuration.nix 中的自动维护选项可实现无人值守。以下是维护示例,执行前确认目标 profile 和回滚窗口。

一、Generation 生命周期总览#

flowchart LR
    A["修改 configuration.nix<br/>或 flake.nix"] --> B["nixos-rebuild switch"]
    B --> C["生成新 Generation<br/>旧版本保留在 /nix/store"]
    C --> D{系统是否正常?}
    D -- 正常 --> E["继续使用"]
    D -- 异常 --> F["nixos-rebuild switch --rollback<br/>或 GRUB 菜单选择旧世代"]
    F --> E
    E --> G["定期清理旧世代<br/>nix-collect-garbage"]
    G --> H["nix-store --gc<br/>回收未引用的 store 对象"]

switch/boot 更新系统 profile 时可以记录新 generation;仅 build 或 test 不等于建立新的系统 profile 世代,旧 generation 通常保留,直到手动或自动维护删除;能否回滚取决于保留的 profile 和产物;只有显式删除 generation 并执行垃圾回收后,对应的 /nix/store 路径才会被真正释放。

二、常用命令速查表#

操作 命令 说明
列出所有系统世代 sudo nixos-rebuild list-generations NixOS 较新版本自带,输出最清晰
列出所有系统世代(通用) sudo nix-env --list-generations --profile /nix/var/nix/profiles/system 传统 profile 的通用接口
列出当前用户环境世代 nix-env --list-generations 用户级 profile
回滚到上一个世代 sudo nixos-rebuild switch --rollback 立即切换,无需重启
切换到指定世代(如 204) 先 sudo nix-env --profile /nix/var/nix/profiles/system --switch-generation 204,再 sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch 更改 profile 与激活是两个步骤
删除指定世代 sudo nix-env --profile /nix/var/nix/profiles/system --delete-generations 205 206 删除 205、206 号
只保留最近 5 个 sudo nix-env --profile /nix/var/nix/profiles/system --delete-generations +5 +N 表示保留最新 N 个
删除 30 天前的世代 sudo nix-env --profile /nix/var/nix/profiles/system --delete-generations 30d 按时间清理
删除旧世代并回收空间 sudo nix-collect-garbage -d 删除所有旧世代 + GC,最常用
按时间清理并回收 sudo nix-collect-garbage --delete-older-than 30d 保留近 30 天,更安全
仅回收未被引用的 store 对象 sudo nix-store --gc 不删世代,只清未引用路径
预览将被删除的内容 sudo nix-store --gc --print-dead 列出"死"对象,不实际删除
开机时通过 GRUB 回滚 启动菜单选 "NixOS - All configurations" 选择任意历史世代启动

提示:nix-collect-garbage -d 相当于先对工具找到的 profiles 执行 nix-env --delete-generations old,再执行 nix-store --gc,执行后将无法回滚到已被删除的世代。

三、清理 /nix/store 空间#

1. 标准两步清理流程

# 第一步:删除 14 天前的系统世代
sudo nix-env --delete-generations --profile /nix/var/nix/profiles/system 14d
# 第二步:只回收未引用的 store 对象,不再扩大历史删除范围
sudo nix-store --gc

此流程将历史删除范围限定在指定系统 profile,先删世代再 GC,否则被世代引用的包不会被回收。

2. 优化存储(硬链接去重)

sudo nix-store --optimise

对相同的 store 文件内容进行硬链接去重,节省量取决于重复内容,可配合 GC 定期执行。

四、在 configuration.nix 中配置自动维护#

把这些选项写进 /etc/nixos/configuration.nix,rebuild 后即可实现自动清理,无需手动跑命令:

{ config, pkgs, ... }:
{
  # 限制 GRUB 启动菜单中保留的世代数量(建议 10-20)
  boot.loader.grub.configurationLimit = 20;
  # 自动垃圾回收
  nix.gc = {
    automatic = true;
    dates = "weekly";              # 每周执行,也可用 "03:30" 指定时间
    options = "--delete-older-than 30d";  # 只删 30 天前的世代
  };
  # 自动优化存储(硬链接去重)
  nix.settings.auto-optimise-store = true;
  # 设置构建时尝试自动 GC 的可用空间阈值(不是 store 容量硬限制)
  nix.extraOptions = ''
    min-free = ${toString (5 * 1024 * 1024 * 1024)}
    max-free = ${toString (10 * 1024 * 1024 * 1024)}
  '';
}

nix.gc.automatic 是官方推荐做法,可以避免 /nix/store 无限膨胀;boot.loader.grub.configurationLimit 则从源头限制 GRUB 菜单条目数量,避免启动列表过长。

五、进阶技巧#

1. 用 nh 简化操作

nh(nix helper)是社区流行的封装工具,提供 nh os switch、nh os generations 等更友好的命令,并能在 rebuild 后显示配置 diff。

2. 新一代 nix 命令

新 CLI 提供用 nix profile 系列命令管理世代:

sudo nix profile history --profile /nix/var/nix/profiles/system          # 查看历史
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 7d  # 清理 7 天前

社区配置仓库中常见这种写法。

3. 系统无法启动时的回滚

即使系统进不去桌面,NixOS 默认在 GRUB 菜单保留 "NixOS - All configurations" 子菜单,列出未删除且在启动菜单保留范围内的历史世代,直接选择即可回到上一个可用状态;这是最后一道保险。

4. 安全清理建议

  • 执行 nix-collect-garbage -d 前确认当前世代稳定,因为删除后无法回滚。
  • 生产服务器建议用 --delete-older-than 30d 而非 -d,保留一段时间的回滚窗口。
  • 大版本升级后先验证运行和回滚方案,再按保留策略清理;菜单条目限制不会自动删除 profile 历史或释放全部 store 空间。

把上述命令和配置组合起来,基本能覆盖从日常回滚到长期磁盘维护的全部场景:nixos-rebuild list-generations 看状态、--rollback 救急、nix-collect-garbage --delete-older-than 定期清,再配 nix.gc.automatic 自动兜底。


参考与延伸

  1. NixOS 手册 ↗
  2. Nix 语言手册 ↗
  3. Nix:垃圾回收与 profile 范围 ↗
  4. Nix:wipe-history ↗

根据技术笔记重新整理,示例使用通用名称。

沿专题继续阅读

NixOS 系统基础与配置

  1. 01NixOS:声明式系统的基础
  2. 02安装 NixOS:介质、分区与初始配置
  3. 03NixOS 配置基础:选项与模块
  4. 04用 Flake 与 Home Manager 管理系统
  5. 05NixOS 命令行:新旧接口与日常维护
  6. 06NixOS 世代管理与垃圾回收
  7. 07Specialisation:一个世代的多个配置变体
  8. 08配置可重现,应用为什么还会“失忆”?
CONTINUE READING / 下一篇Specialisation:一个世代的多个配置变体

在一个基础配置下声明变体,并区分运行时激活与重启生效。