Rollback 回滚快照,但空间不足

Rollback 回滚快照,但空间不足,rollback,snapshot,zfs,Rollback,Snapshot,Zfs,我有一个1TB的zpool和一个700GB的卷,其中有一个干净的快照,例如: zpool1 zpool1/volume1 zpool1/volume1@snap1 将500GB数据写入卷后,其写入属性也将增长到500GB 然后,我试图回滚到快照,但出现了“空间不足”的错误 zpool是否需要额外的空间来回滚具有较大写入值的快照?或者有人能解释它失败的原因吗?回滚到快照需要一点空间(用于更新元数据),但这非常小 从您所描述的情况来看,我认为您在同一池/配额组中编写的任何内容此时都会因ENOSPC

我有一个1TB的zpool和一个700GB的卷,其中有一个干净的快照,例如:

zpool1
zpool1/volume1
zpool1/volume1@snap1
将500GB数据写入卷后,其写入属性也将增长到500GB

然后,我试图回滚到快照,但出现了“空间不足”的错误


zpool是否需要额外的空间来回滚具有较大写入值的快照?或者有人能解释它失败的原因吗?

回滚到快照需要一点空间(用于更新元数据),但这非常小

从您所描述的情况来看,我认为您在同一池/配额组中编写的任何内容此时都会因
ENOSPC
而失败。如果您运行
zpool status
,我敢打赌您会看到整个池几乎完全满了,或者如果您使用的是配额,那么您可能已经用完了它所适用的所有配额组。如果这不是您所期望的,则可能是您正在使用镜像或RAID-Z,这会导致写入重复字节(以允许损坏恢复)。您可以通过查看
zfs列表中的
使用的
物理字节(而不是
写入的
逻辑字节)来判断这一点


在快照之后添加的大部分数据可以在回滚完成后删除,但不能在此之前删除(因此回滚必须保留该数据,直到完成)。

在搜索zfs源代码(dsl_dataset.c)后,我发现dsl_dataset_rollback_check()的最后一部分可能解释了此限制:

 * When we do the clone swap, we will temporarily use more space
 * due to the refreservation (the head will no longer have any
 * unique space, so the entire amount of the refreservation will need
 * to be free).  We will immediately destroy the clone, freeing
 * this space, but the freeing happens over many txg's.
 *
unused_refres_delta = (int64_t)MIN(ds->ds_reserved,
    dsl_dataset_phys(ds)->ds_unique_bytes);

if (unused_refres_delta > 0 &&
    unused_refres_delta >
    dsl_dir_space_available(ds->ds_dir, NULL, 0, TRUE)) {
    dsl_dataset_rele(ds, FTAG);
    return (SET_ERROR(ENOSPC));
}
因此,卷的“avail”必须大于“refreserv”才能执行回滚。
只有精简卷才能通过此检查。

谢谢Dan,回滚必须按您所说的那样保留数据。我已经检查了zfs源代码,并做了一些测试来验证它。