本文主要整理若干 ZFS 运维片段:raidz2 池出现 checksum 错误与永久损坏文件时的 zpool status 解读、zpool clear 的作用边界、ARC 上限配置入口,以及一次 mirror 场景下的 fio 吞吐摘要。
原稿偏流水账与大段 fio 原文,此处收敛为可复查的操作记录。zpool clear 不能修复已永久损坏的数据,只能清设备错误计数;损坏文件仍需从备份恢复或删除后重拷。池名、路径已按历史环境保留结构,敏感主机名做了弱化。
问题现象
某 TrueNAS / OpenZFS 池(示例名 Helium,拓扑 raidz2)状态为 DEGRADED,zpool 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>
- 先看
state、status/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 手册,确认影响。
建议后续步骤(通用)
- 从备份恢复 permanent errors 中的文件,或删除后重传。
- 对池执行
zpool scrub <pool>,确认错误是否下降/清零。 - 持续监控 SMART、线缆、背板与电源;多盘同时 CKSUM 有时指向控制器/背板而非“十块盘同时坏”。
- 无完整备份时,评估整池恢复策略(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 jobs | write | ~187k | ~2922 MiB/s |
| 16kB,120 jobs | read | ~433k | ~6764 MiB/s |
| 128kB,120 jobs | read | ~53.4k | ~6677 MiB/s |
| 128kB,120 jobs | write | ~29.7k | ~3716 MiB/s |
| 128kB readwrite | read/write 各约 | ~25.4k | ~317x MiB/s |
注意:高 numjobs + 深队列测的是聚合峰值,受 ARC、压缩、记录大小、是否 direct、盘型与当时负载影响极大;仅作同机相对对比素材。完整 percentile 原文过长,需要时从备份日志取。
验证结果
| 动作 | 如何判断 |
|---|---|
| clear 后 | zpool status 设备 ONLINE,CKSUM 计数清零或不再攀升 |
| 数据修复 | permanent errors 列表消失;业务文件可正常读校验 |
| scrub | repaired/errors 符合预期,无新增 permanent errors |
| ARC | zfs_arc_max 与 arcstats 与配置一致 |
注意事项
- 多盘同时 CKSUM 不要只换盘;先查线缆、HBA、供电与固件。
- 媒体库等大文件损坏时,优先单文件恢复,避免误
destroy。 - fio 会打满 IO,勿在生产高峰对共享池压测。
- 截图资产若存在于 vault/assets,上站时需迁到
blog-content/assets/posts/...并改链接(当前草稿可不强制带图)。
参考资料
- OpenZFS:ZFS-8000-8A
- OpenZFS 文档
zpool(8)/zfs(8)手册(本机 man)