为什么 ZFS 重新同步器会扫描整个池?

Jas*_*nes 7 hardware solaris zfs hard-drive omnios

我有一个 zpool,我刚刚更换了一个故障磁盘,并开始重新同步到新磁盘。

我不明白的是,zpool status当 vdev 的大小为 ~30TB 时,为什么说它要扫描 129TB。当我查看时,iostat -nx 1我可以看到 vdev 中的 5 个磁盘读取量很大,而新磁盘的写入量也很大。所以 zfs 不会像它所说的那样扫描所有数据。

# zpool status tank3 |head
  pool: tank3
 state: ONLINE
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Thu Apr 30 09:59:15 2015
    61.2T scanned out of 129T at 3.03G/s, 6h23m to go
    946G resilvered, 47.34% done
Run Code Online (Sandbox Code Playgroud)

我想说每个 vdev 都是相互独立的,所以一个 resilver 不应该需要对其他 vdev 进行任何扫描。为什么 zfs 在重新同步时扫描所有使用的磁盘空间?

noi*_*cky 10

重新同步(和清理)涉及遍历池的整个 B 树,并重新同步丢失磁盘上的块。

如果不遍历树中的每个 txg,它就无法知道丢失的磁盘上会有哪些块,因此它会扫描整个元数据宇宙以查找池。

它不一定要读取所有数据,只需要足够的元数据来确定它是否确实需要读取相应的数据。您可能会看到进度信息比实际读取的数据量上升得更快,因为它实际上是在计算它读取的元数据所引用的数据量。


Chr*_*s S 4

重新同步是一个 vdev 操作;正如您所暗示的,仅使用该 vdev 中的存储设备来重建新设备。我不确定为什么它引用了 zpool 的完整大小,但我怀疑开发人员借用了清理函数的代码,或者它只是引用了完整的 zpool 大小,因为这将是最坏的情况。