回滚快照但 运行 出 space
Rollback snapshot but run out of space
我有一个 1TB 的 zpool 和一个 700GB 的卷以及一个干净的快照,例如:
zpool1
zpool1/volume1
zpool1/volume1@snap1
将500GB的数据写入volume后,写入的属性也增长到500GB。
然后我尝试回滚到快照,但出现 "out of space" 错误。
zpool 是否需要额外的 space 来回滚写入值较大的快照?或者谁能解释为什么会失败?
回滚到快照需要一点space(用于更新元数据),但这非常小。
根据您的描述,我预计此时您在同一池/配额组中编写的几乎所有内容都会失败并显示 ENOSPC
。如果你 运行 zpool status
,我敢打赌你会看到整个池几乎都满了,或者如果你正在使用配额,也许你已经用完了它适用的所有配额组。如果这不是您所期望的,可能是您正在使用镜像或 RAID-Z,这会导致写入重复字节(以允许损坏恢复)。您可以通过查看 zfs list
.
中的 used
物理字节(而不是 written
逻辑字节)来判断这一点
您在快照之后添加的大部分数据可以在回滚完成后删除,但不能在此之前删除(因此回滚必须保留这些数据直到完成)。
在搜索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" 才能执行回滚。
只有 thin-volume 可以通过此检查。
我有一个 1TB 的 zpool 和一个 700GB 的卷以及一个干净的快照,例如:
zpool1
zpool1/volume1
zpool1/volume1@snap1
将500GB的数据写入volume后,写入的属性也增长到500GB。
然后我尝试回滚到快照,但出现 "out of space" 错误。
zpool 是否需要额外的 space 来回滚写入值较大的快照?或者谁能解释为什么会失败?
回滚到快照需要一点space(用于更新元数据),但这非常小。
根据您的描述,我预计此时您在同一池/配额组中编写的几乎所有内容都会失败并显示 ENOSPC
。如果你 运行 zpool status
,我敢打赌你会看到整个池几乎都满了,或者如果你正在使用配额,也许你已经用完了它适用的所有配额组。如果这不是您所期望的,可能是您正在使用镜像或 RAID-Z,这会导致写入重复字节(以允许损坏恢复)。您可以通过查看 zfs list
.
used
物理字节(而不是 written
逻辑字节)来判断这一点
您在快照之后添加的大部分数据可以在回滚完成后删除,但不能在此之前删除(因此回滚必须保留这些数据直到完成)。
在搜索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" 才能执行回滚。 只有 thin-volume 可以通过此检查。