nixos入主系统:ntfs,ext4,zfs,raid的分析

nixos系统的硬盘规划

现状(2026-10-08 实测)

盘型号容量分区
nvme0n1BC711 NVMe SK hynix119.2 GiBp1 1 GiB vfat /boot(用 161 MiB)· p2 118.2 GiB ext4 /(用 35 G,剩 76 G)
nvme1n1CWESR02TBTLCZ-27J-21.86 TiBp1 551 MiB vfat BWINEFI · p2 295.1 GiB ntfs s500win · 未分配约 1.57 TiB

目标布局:盘1 入主

盘1 nvme1n1  1.86 TiB  —— 主力盘
p1 551 MiB vfat BWINEFI Windows ESP,原样保留
p2 295.1 GiB ntfs s500win 后备 Win,原样保留(零成本,将来可回收)
p3 1 GiB vfat NIXESP 新建:NixOS 自己的 ESP(与 Windows 分开)
p4 256 GiB ext4 / NixOS root
p5 ~1.32 TiB 待定 /s500data 挂载点(文件系统待定)
盘2 nvme0n1 119.2 GiB —— 原样不动 = 一台完整可启动的备用 NixOS

/s500data 下平铺(同一层,不嵌套):
vms/ repos/ docker/ <个人数据目录…>

分盘判据

决策理由
root 倾向 ext4(不倾向 ZFS)NixOS generation 本身就是 root 的时点回退(启动菜单切代),ZFS root 增量价值小;ext4 保住「任何 U 盘都能 mount 修」
挂载点命名用业务 / 设备名不用 dataset / pool / tank 这类技术概念名 —— 名字不得预设技术选型,否则读方案的人会默认朝某个技术走
/s500data 的文件系统不预设判据:要快照 / 校验 / zfs send 到冷备 → ZFS;要任何 U 盘可 mount、可 fsck → ext4。技术选择留到建盘前定
root 给 256 GiB(比现在大一倍)ZFS 只能长不能缩,所以 root 给宽是安全的;root 增长源只有 /nix/store,配自动 gc 后稳定
ESP 与 Windows 分开Windows 功能更新会重写引导项;分开后 NixOS 的 generation 回退链不受盘1 任何操作波及
盘2 原样保留零成本救援系统,也是未来唯一扩容位(内部仅 2 个 M.2 位,已占满)
不建任何冗余内部没有第三盘位,mirror / raidz 物理上无从谈起

配套三件(缺一不可)

nix.gc.automatic = true;   nix.gc.options = "--delete-older-than 14d";
nix.settings.auto-optimise-store = true; # 不给 gc,/nix/store 无界增长,root 迟早撑爆
boot.loader.systemd-boot.configurationLimit = 10; # ESP 写满 = rebuild 直接失败
boot.extraModprobeConfig = "options zfs zfs_arc_max=17179869184"; # 16 GiB(默认吃 50% = 32 G)

不可逆点(建盘前必须一次定对;标 ZFS|的四项仅在选 ZFS 时适用)

项当前选择定错能改吗
ZFS|加密开 / 不开不可逆:2.4 原生加密必须建 dataset 时开,明文不能转
ZFS|ashift12(4K,NVMe 必须)建池定死
ZFS|pool 名 + dataset 划分见布局拆分容易,合并要 send/receive 重写
ZFS|recordsize(每 dataset)按用途分(VM 大块 / DB 小块)只对之后新写入的文件生效
root 与数据盘的容量切分256 GiB / 1.32 TiB事后不便宜

待定

  • p4 root 用 ext4 还是 ZFS(判断倾向 ext4)
  • p5 /s500data 用 ext4 还是 ZFS(判断倾向 ZFS:快照 / zfs send / 校验正是数据层缺的)
  • 若选 ZFS:加密开不开(必须建 dataset 时定,事后不可逆)
  • 盘1 的 295 GiB s500win 分区保不保(倾向保留)
  • 待实测:盘1 那块 2 TB 的实际读写性能(决定「数据放这块盘」是升级还是降级)

ntfs,ext4,zfs,raid的分析

四种的定位

名称定位快照校验缩容跨机可修
ntfsWindows 文件系统,日志 + ACL + 压缩 + 卷影副本卷影副本无端到端校验和能Windows 原生,Linux 需 ntfs-3g
ext4Linux 通用日志文件系统无无能(离线 resize2fs + fsck)任何 Linux 直接 mount
zfs存储池管理 + 文件系统 + 卷管理三合一有,O(1)有,每块数据带校验和只能长,永不能缩需 ZFS 2.4+ 用户态
raid把 N 块盘的地址空间映射成一个逻辑地址空间的存储虚拟化,本身不是文件系统无无(parity 只保证可读,不保证语义正确)不适用不适用

抽象链对位(Windows 侧参照)

ZFS 的定位:云服务商的存储方案,不是个人电脑的物理存储管理。判据:它的能力清单(快照 / send-receive / quota / 池扩展 / 校验)就是云块存储的产品功能表;单盘机上只用到一小部分,却承担全部复杂度。Windows 侧的同位物是 Storage Spaces + ReFS,不是 diskpart —— diskpart 停在「分区」这一层。

名称抽象链它管什么
diskpart物理盘 → 分区 → 卷 → 盘符 → NTFS只切盘子;不管完整性、快照、校验
Storage Spaces + ReFS物理盘 → 池 → space(虚拟盘)→ 卷 → ReFS池化、mirror / parity / simple;ReFS 带校验和与 integrity stream
ZFS物理盘 → vdev → pool → dataset / zvol → 挂载点上面两件 + 快照 + send/receive + 压缩 + quota + 校验

Storage Spaces / ReFS 细节未实测。

ZFS 一体两面:机制 · 收益 · 代价

先破一个宣称:单盘 ZFS 不提供 durability,和 ext4 一样会丢;增量只在时间维度(快照 / send)与可见性(校验)。

机制(ZFS 术语)收益面代价 / 边界
冗余 vdev(mirror / raidz)单盘失效仍可读;raidz 用 parity 换容量效率本机不适用 —— 只有一个数据盘位,单盘无冗余可言
校验和 + scrub(self-heal 的输入)每块数据带校验和;scrub 定期扫描可发现静默损坏self-heal 需要冗余;无冗余只能发现不能修。checksum error 的正确反应是换盘 + 从备份恢复
COW 事务模型(copy-on-write / TXG)写入原子;快照与回退的地基随机小写有写放大,数据库、容器 overlay 是弱区
快照(snapshot / hold)O(1) 创建;时间点回退,普通文件系统没有的维度不是备份 —— 与池同生共死,池毁快照全没;被快照引用的块延迟释放,持续占空间
复制原语(send / receive)增量、可校验、可自动化 —— 是「另一份数据在另一个介质上」的实现手段依赖另置介质 + 定期任务;它只提供手段,保留多久要自己定策略
池化与配额(pool / quota / reservation)空间池内共享不切死;管理粒度细于分区池只能扩不能缩 —— 划出去的空间拿不回来,一次定对;vdev 拓扑建池时定型
寻址与块参数(ashift / recordsize)可对齐 4K 扇区;recordsize 可按用途调(VM 大块 / DB 小块)建池、建 dataset 时定;recordsize 只对之后新写入的文件生效,全量改要 send/receive 重写
压缩(lz4 / zstd)1.5–2x 常见,CPU 代价低到可忽略压缩率不是宣传值;已写入的数据改算法不追溯
ARC 读缓存用内存换读命中率,热点数据不落盘默认上限 = 物理内存 50%(64 G 机上 32 G),与 VM 争抢,必须设 zfs_arc_max
原生加密(AES-GCM / keylocation)dataset 级加密,可用 passphrase 或 keyfile必须建 dataset 时开,明文不能转,不可逆;解锁发生在 initrd;密钥丢了数据也丢了
属性系统(properties)策略可下推到 dataset(quota / mountpoint / com.sun:auto-snapshot);NixOS 的声明式开关就是驱动它属运行期状态,Nix 不描述它;「只对新写入生效」的那些属性改不动旧数据
交付形态(树外内核模块 zfs.ko + 用户态 CLI)独立于内核演进;控制面就是命令行 —— 无固件、无 option ROM、无独立管理界面与内核版本强耦合(跑太快就构建失败或起不来;linuxPackages.zfs 属性名 2025-01 已被 nixpkgs 删除);救援门槛高一档 —— ext4 盘任何 Linux U 盘可 mount,ZFS 盘要 2.4+ 用户态

ZFS 的操作管理方式

ZFS 没有固件成分:无 BIOS 配置页、无 option ROM、无独立管理界面(TrueNAS / Cockpit 是第三方应用)。它是纯软件 —— 内核里 zfs.ko + 用户态 zpool / zfs 命令。

维度硬件 RAIDZFS
存在形态控制器固件里的 option ROM内核模块 zfs.ko + 用户态 CLI
配置入口开机 Ctrl+I / BIOS 里的配置页系统跑起来之后的命令行
配置存放控制器 NVRAM + 盘上 metadata池自身(写在盘的 label / uberblock 上)
独立管理界面有(固件阶段)无
换系统还认识吗认识(固件层,与 OS 无关)需目标 OS 装了 ZFS 驱动
创建时机装机 / 进 BIOS 时系统运行中用命令行创建
使用时机每次开机固件阶段就位initrd(root 在 ZFS 上时)或 systemd 阶段

关键区别:diskpart 是控制面工具,ZFS 是常驻数据通路。diskpart 改完分区表就退出;ZFS 的每次文件读写都真的走在 zfs.ko 里,zpool / zfs 只是它的控制面。它的全部代价来自这一点:吃 ARC、写放大、与内核版本耦合。

与 NixOS 的边界:Nix 管「哪个 dataset 挂到哪个路径」,不管池里长什么样。fileSystems."/s500data" = { device = "s500data"; fsType = "zfs"; }; 会被用来反推要 import 哪个池并生成 zfs-import-<池名>.service;挂载由 ZFS 自带的 systemd 单元做。池内形态(几个 dataset、recordsize、快照、属性)是运行期状态,用 zfs 命令改 —— 边界是「配置 vs 数据」。

NixOS 声明式开关作用
boot.zfs.extraPools额外要在启动时 import 的池
boot.zfs.requestEncryptionCredentialsinitrd 中解锁加密 dataset
boot.zfs.forceImportRoot强制 import root 池(26.11 起默认 false)
services.zfs.autoSnapshot自动快照(frequent / hourly / daily / weekly / monthly 各自保留数)
services.zfs.autoScrub定期 scrub(默认 monthly,带随机延迟)
services.zfs.trim / services.zfs.zed定期 TRIM;ZFS 事件守护

结论

  • ZFS 的增量价值不在冗余:它在普通文件系统之外多给了时间维度(快照 / send)与可见性维度(校验)。
  • 单盘机上只应取这两样 —— 「防丢数据」买不到,也不该买。
  • 有价值排序:send / 快照 >> 压缩 > 校验。
  • 净影响:ZFS 在盘1 上就是「带快照与校验的文件系统」;真正的「不会丢」由 /s500data 定期 zfs send 到移动硬盘(离线、另一个物理介质、可校验)承载 —— 这正好就是备份层要建的东西。