记一次 ZFS 存储池恢复实战

3 天前
 lerry

今天下午,我正准备给新起的项目配置数据库,发现本地 NAS 上的 PostgreSQL 数据库突然连接不上了。起初发现是硬盘满了,经过排查,更糟,ZFS 存储池不见了。这台 Nas 是用来备份的,因为 whale 池子不见了,定时备份命令把系统盘存满了。本文记录了这次数据恢复的全过程,希望能给遇到类似问题的朋友一些参考。

问题发现

  1. PostgreSQL 数据库无法连接
  2. 系统提示硬盘空间已满
  3. 关键的 /whale 存储池完全消失
  4. 通过 lsblk 确认物理硬盘仍在线

问题诊断

执行 zpool import 命令后,系统返回了错误信息,看起来很严重:

# zpool import -d /dev/disk/by-id/ata-WDC_WUH721816ALE6L4_2BJNGLGN-part1
pool: whale
id: 6556284763754827846
state: FAULTED
status: The pool metadata is corrupted.
action: The pool cannot be imported due to damaged devices or data.
	The pool may be active on another system, but can be imported using
	the '-f' flag.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-72
config:

	whale                               FAULTED  corrupted data
	  ata-WDC_WUH721816ALE6L4_2BJNGLGN  ONLINE

存储池处于 FAULTED 状态,元数据遭到损坏。即使使用 -f 参数强制导入也未能解决问题。

解决过程

我把zpool import的回显和提示的网址发给 Cursor ,在 AI 助手的建议下,我们采取了以下步骤:

  1. 首先使用 zpool import -Fn whale 进行"dry run"测试,结果令人欣慰:
Would be able to return whale to its state as of 2025 年 01 月 03 日 星期五 20 时 36 分 47 秒.
Would discard approximately 5 seconds of transactions.
  1. 确认只会损失 5 秒的数据后,果断执行了实际恢复操作:
    • 运行 zpool import -F whale
    • 重启系统以确保所有服务正常运行
    • 随机查看了一些文件,没有发现损坏的迹象
    • 执行 zpool scrub whale 进行数据完整性检查

事后分析

昨天晚上,我回到家发现 Mac mini 关机了,查看 Nas 的 uptime 只有 16min ,说明家里断过电。这很可能是因为断电导致的存储池损坏。

经验总结

  1. ZFS 的自愈能力确实强大,即使遇到元数据损坏也有恢复的可能
  2. 在进行重要操作前,使用 -n 参数进行干运行测试是个好习惯
  3. UPS 电源保护对于 NAS 系统来说至关重要
  4. 定期备份依然是数据安全的最后防线

虽然这个池子只是备份数据,如果丢失了也很麻烦。还好虚惊一场。AI 确实强大,文档链接直接丢给它就能给出方案。

https://lerry.me/post/2025/01/zfs-storage-pool-recovery

1662 次点击
所在节点    Linux
15 条回复
bkmi
3 天前
备份盘不组个镜像吗
kyonn
3 天前
ZFS 也是 COW 机制的吧, 为什么断电会导致存储池丢失呢
heimoshuiyu
3 天前
一切没有配置监控和通知的存储方案最终结局都是爆炸
thinkm
3 天前
收藏了 我也用的 ZFS 以防万一
jhytxy
3 天前
就家庭用户而言

我觉得稳压电源比 ups 更合适
ups 那个电池就是大坑
家里云的硬盘一般断电也没事,只要不开上电自动开机就行了
怕的是连续断电
硬盘自检恢复的时候再掉一次电肯定就废了
msg7086
2 天前
ZFS 是 COW ,断电按理只会掉最后写入的数据,池是不会坏的。
riceball
2 天前
我的一点使用 ZFS 的❄️的教训:

1. 必须至少上 RegRAM,还有就是尽可能多的 RAM,至少要满足最小值,具体计算我忘记了,根据你组的磁盘总大小计算,尤其是你启用了 deduplication, 它严重依赖 RAM ,如果 RAM 有错误,写入就会错误!
2. 当 ZFS 快写满了,如果这时候仓库错误,恢复几乎不太可能,折腾几天,几乎进度不动。我的数据...
lerry
2 天前
@bkmi 主存储有 z1+snapshot ,备份池子单盘+snapshot

@heimoshuiyu 主存储有配置 zfs-zed ,备份机器经常折腾,上次从 TrueNas 换成 Debian 忘记开了

只做存储的话,TrueNas 确实可以,监控快照很好配置。平时还想干点别的事,TrueNas 限制还是太多
ryd994
2 天前
@riceball 没事别开 dedup 。一般人使用不需要 dedup 。dedup 需要 1GB/TB 。不开 dedup 的话 8G 都足够,无论多大的硬盘
riceball
2 天前
@ryd994 就因为 zfs 有 dedup 才用的,省硬盘。如果不用的话,为啥不直接 mdadm,组软 raid ,后期直接上 raid 卡也成。
ryd994
2 天前
@riceball 建议你实际看一下 dedup ratio 是多少
zpool get all whale

对于大部分人来说,compression 基本免费(现代 CPU 很强大),dedup 基本不值得。因为 dedup 的性能开销很大而且实际效果不佳。重复一遍:一般人不需要 dedup 。

为什么用 zfs 而不是 mdadm:因为 zfs 有校验,定期 resilver 可以处理冷错误。普通 raid 无法检测不一致的情况,因为 raid 的设计目标就是假设磁盘故障就完全掉线,既不会超时,也不会返回错误数据。这个假设对于短期储存的应用数据是足够的。但是对于长期储存的数据安全是不够的。

raid 卡就更别说了。数据安全和硬件绑定。而且性能非常有限。以前 CPU 羸弱,raid 卡可以分担负载所以有用。现在 CPU 很强,高性能阵列要靠 vroc ,raid 卡纯减速了。

带 bbu cache 的 raid 卡性能会比较好,但仍然受制于 pcie 带宽。企业级 SSD 自带掉电保护,所以 bbu cache 也不会有明显的性能增益。而且价格很贵。
riceball
1 天前
@ryd994 崩溃后,已经没用 zfs 了,当时我主用 zfs ,连 root 和 boot 分区都是 zfs, 导致挂了后不能启动,一直卡在 scrub.

另外,现在想来,zfs 最好还是要经常 cron scrub 。我的 ZFS 系统当时已经稳定工作很长的一段的时间(大概 3 年),一直到仓库快满了,才出现的问题。

对桌面 PC 来说,是的,compression 不是问题。但是基于应用级的压缩无法做到压缩后的数据在整个盘中只保存一份,而 dedup 能做到。

自从 zfs 挂了,我现在用的就是支持 bbu cache 的 raid 卡,当时买成 900 多,带超级电容,1G RAM ,现在只要 400 多(不带超级电容)。raid 上是纯机械硬盘,放需要安全保存的数据; ssd 只放 boot 分区,以及需要加速的应用和数据。
yianing
1 天前
@kyonn zfs 的 cow 是说的快照功能,和存储池断电丢数据有什么关系?
kyonn
1 天前
@yianing 就是 6 楼的疑问, 照理应该只会丢失最后写入的数据.
kyonn
1 天前
为什么存储池会掉线?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1102533

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX