本文主要整理若干 ZFS 运维片段:raidz2 池出现 checksum 错误与永久损坏文件时的 zpool status 解读、zpool clear 的作用边界、ARC 上限配置入口,以及一次 mirror 场景下的 fio 吞吐摘要。

原稿偏流水账与大段 fio 原文,此处收敛为可复查的操作记录。zpool clear 不能修复已永久损坏的数据,只能清设备错误计数;损坏文件仍需从备份恢复或删除后重拷。池名、路径已按历史环境保留结构,敏感主机名做了弱化。

问题现象

某 TrueNAS / OpenZFS 池(示例名 Helium,拓扑 raidz2)状态为 DEGRADEDzpool status -v 显示多块设备 CKSUM 错误,并列出永久错误文件:

  pool: Helium
 state: DEGRADED
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-8A
  scan: scrub repaired 0B in 00:27:11 with 300 errors on ...
config:
        NAME        STATE     READ WRITE CKSUM
        Helium      DEGRADED     0     0     0
          raidz2-0  DEGRADED     0     0     0
            <vdev-id>  DEGRADED     0     0   688  too many errors
            ...
errors: Permanent errors have been detected in the following files:
        /mnt/Helium/<dataset>/.../<file-a>
        Helium/<dataset>:<0x...>
        /mnt/Helium/<dataset>/.../<file-b>

要点:

  • DEGRADED + 多设备 too many errors:校验错误已累计到“过多”,池仍可能可访问但数据完整性受损。
  • scrub repaired 0B ... with 300 errors:scrub 未能修复这些错误(冗余不足以重建或错误已永久)。
  • Permanent errors:列出的路径/对象 ID 对应数据已不可靠。

环境背景

项目说明(示例)
平台TrueNAS / 通用 OpenZFS
池拓扑raidz2-0(多盘)
错误类型CKSUM(校验)为主
参考文档OpenZFS msg ZFS-8000-8A

具体盘符在 status 中可能以 GUID 形式出现(TrueNAS 常见)。

排查与处理

解读 status

zpool status -v <pool>
  • 先看 statestatus/action 官方建议。
  • READ/WRITE/CKSUM 列定位错误类型。
  • errors: 下列出的文件优先从可信备份恢复;对象 ID 形式(pool/dataset:<0x...>)可能是已删文件或元数据对象,需结合 zdb/业务判断(进阶,本文不展开)。

zpool clear

历史操作:

zpool clear -F Helium
zpool status -v Helium

clear 之后设备状态可回到 ONLINE status 仍可能提示 data corruption,且 Permanent errors 文件列表仍在

 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
...
errors: Permanent errors have been detected in the following files:
        ...

结论:

  • clear:清除 vdev 错误计数,便于观察错误是否再出现。
  • 不能 magically 修好已损坏块;业务上仍要恢复或剔除坏文件,再 scrub 确认。
  • -F 为强制类选项,使用前查阅当前 OpenZFS 手册,确认影响。

建议后续步骤(通用)

  1. 从备份恢复 permanent errors 中的文件,或删除后重传。
  2. 对池执行 zpool scrub <pool>,确认错误是否下降/清零。
  3. 持续监控 SMART、线缆、背板与电源;多盘同时 CKSUM 有时指向控制器/背板而非“十块盘同时坏”。
  4. 无完整备份时,评估整池恢复策略(action 文案已提示)。

ARC 上限(备忘)

限制 ARC 最大内存(示例 4GiB)可在 modprobe 配置中持久化:

echo "options zfs zfs_arc_max=4294967296" | tee -a /etc/modprobe.d/zfs.conf

查看当前统计与参数(路径因发行版可能略有差异):

cat /proc/spl/kstat/zfs/arcstats
cat /sys/module/zfs/parameters/zfs_arc_max
cat /sys/module/zfs/parameters/zfs_arc_min

修改后通常需重载模块或重启才完全生效,生产改 ARC 前评估缓存命中与其它服务内存。具体是否立即生效以当前内核/OpenZFS 行为为准(待确认)。

fio 吞吐摘要(历史环境)

在 mirror 类数据集路径上曾用 fio 做粗测(参数与路径为历史记录,结果不可外推到所有池)。命令形态示意:

fio -directory=<fio-workdir> -ioengine=libaio -bs=16k -size=1G -direct=1 \
  -thread -rw=write -iodepth=16 -runtime=60 -numjobs=120 \
  -name="ZFSMirror 16kB write test" -group_reporting

历史结果数量级摘要:

场景(名称以日志为准)方向约 IOPS约带宽
16kB,120 jobswrite~187k~2922 MiB/s
16kB,120 jobsread~433k~6764 MiB/s
128kB,120 jobsread~53.4k~6677 MiB/s
128kB,120 jobswrite~29.7k~3716 MiB/s
128kB readwriteread/write 各约~25.4k~317x MiB/s

注意:高 numjobs + 深队列测的是聚合峰值,受 ARC、压缩、记录大小、是否 direct、盘型与当时负载影响极大;仅作同机相对对比素材。完整 percentile 原文过长,需要时从备份日志取。

验证结果

动作如何判断
clear 后zpool status 设备 ONLINE,CKSUM 计数清零或不再攀升
数据修复permanent errors 列表消失;业务文件可正常读校验
scrubrepaired/errors 符合预期,无新增 permanent errors
ARCzfs_arc_maxarcstats 与配置一致

注意事项

  • 多盘同时 CKSUM 不要只换盘;先查线缆、HBA、供电与固件。
  • 媒体库等大文件损坏时,优先单文件恢复,避免误 destroy
  • fio 会打满 IO,勿在生产高峰对共享池压测。
  • 截图资产若存在于 vault/assets,上站时需迁到 blog-content/assets/posts/... 并改链接(当前草稿可不强制带图)。

参考资料