PAYATHON 2026

Snowflake zero copy clone 删除后的 storage usage 如何计算?

支付小周

结论

如果只计算 clone group 当前仍被存活表引用的去重数据,并且假设 p3 已不再受 Time Travel、Fail-safe 或后台清理延迟影响,那么你的理解基本正确:

  1. p1 仍可归属于 T1,同时由 T3 继续引用。
  2. p2 原本由 T2 承担存储 ownership。删除 T2 后,只要 T3 仍在引用 p2,ownership 就需要转移给 clone group 中仍存活的表,通常可以理解为转移给 T3。
  3. 此时 clone group 的去重存储量为:

[ p0+p1+p2+p4=5+5+5+2=17\text{ MB} ]

不过,TIME_TRAVEL = 0 不代表删除 T2 后存储量会立即降到 17 MB。永久表仍可能受 Fail-safe 保留期影响,已删除的数据也可能在等待后台异步清理。因此,17 MB 是稳定状态下去重后的 active storage,不一定等于删除操作刚完成时,账单或系统视图中显示的数字。

为什么是 17 MB

删除 T2 前,各表引用的数据如下:

Partition大小引用者
p05 MBT1
p15 MBT1, T2, T3
p25 MBT2, T3
p35 MBT2
p42 MBT3

三个表的逻辑大小之和为:

[ 10+15+12=37\text{ MB} ]

但 zero-copy clone 会共享相同的底层 micro-partitions,不能直接把各表的逻辑大小相加。删除 T2 前,clone group 去重后的数据量为:

[ p0+p1+p2+p3+p4=22\text{ MB} ]

删除 T2 后:

  • p0 仍由 T1 引用;
  • p1 仍由 T1 和 T3 引用;
  • p2 仍由 T3 引用;
  • p3 不再被任何存活表引用;
  • p4 仍由 T3 引用。

等到 p3 的所有数据保留期结束,并完成物理清理后:

[ 22-5=17\text{ MB} ]

ownership 与 reference 的区别

这里需要区分两个概念:

  • Reference:哪些表的当前版本仍能读取该 micro-partition。
  • Ownership:Snowflake 在内部把共享存储归属到 clone group 中的某个对象,用于跟踪生命周期和存储用量。

同一份共享数据可以由多个表引用,但不会因为存在多个引用而保存多份。

因此,T1 保持对 p1 的 ownership,并不影响 T3 引用同一个 p1。同样,删除 T2 时,p2 不能随 T2 一起清除,因为 T3 仍然依赖它。为了继续正确跟踪其生命周期,ownership 必须由仍存活的对象承接。

ownership 转移不等于复制了 5 MB 数据。通常只有内部归属发生变化,底层 micro-partition 无需重新复制。

删除后的计算步骤

可以按下面的顺序计算:

  1. 列出 clone group 中的所有底层 partitions。
  2. 记录每个 partition 当前被哪些存活表引用。
  3. 移除目标表对应的引用。
  4. 仍有至少一个存活引用的 partition 只计算一次。
  5. 对已经没有存活引用的 partition,继续检查 Time Travel、Fail-safe 和后台清理状态。
  6. 等所有保留期结束后,再从稳定状态的存储量中排除这些 partitions。

本例达到稳定状态后的引用关系为:

T1 -> p0, p1
T3 -> p1, p2, p4

取并集:

{p0, p1} ∪ {p1, p2, p4}
= {p0, p1, p2, p4}

因此:

5 MB + 5 MB + 5 MB + 2 MB = 17 MB

查询实际存储指标

在实际环境中,无法直接按照示例中的 p0、p1 查询 micro-partition ownership,但可以查看账户级的表存储指标:

SELECT
    table_catalog,
    table_schema,
    table_name,
    active_bytes,
    time_travel_bytes,
    failsafe_bytes,
    retained_for_clone_bytes,
    deleted
FROM snowflake.account_usage.table_storage_metrics
WHERE table_schema = 'YOUR_SCHEMA'
  AND table_name IN ('T1', 'T2', 'T3')
ORDER BY table_name;

主要关注这些字段:

  • ACTIVE_BYTES:当前表的 active data。
  • TIME_TRAVEL_BYTES:因 Time Travel 而保留的数据。
  • FAILSAFE_BYTES:进入 Fail-safe 的数据。
  • RETAINED_FOR_CLONE_BYTES:原对象因 clone 仍在引用而必须保留的数据。
  • DELETED:对象是否已删除。

如果需要观察删除前后的变化,可以先保存一份快照:

CREATE OR REPLACE TEMPORARY TABLE storage_before_drop AS
SELECT *
FROM snowflake.account_usage.table_storage_metrics
WHERE table_schema = 'YOUR_SCHEMA'
  AND table_name IN ('T1', 'T2', 'T3');

然后删除表:

DROP TABLE YOUR_DATABASE.YOUR_SCHEMA.T2;

随后再次查询:

SELECT
    table_name,
    active_bytes,
    time_travel_bytes,
    failsafe_bytes,
    retained_for_clone_bytes,
    deleted
FROM snowflake.account_usage.table_storage_metrics
WHERE table_schema = 'YOUR_SCHEMA'
  AND table_name IN ('T1', 'T2', 'T3')
ORDER BY table_name;

ACCOUNT_USAGE 视图通常存在数据延迟,不适合验证删除操作发生后几秒内的即时变化。

注意事项

TIME_TRAVEL = 0 不等于立即物理删除

Time Travel retention period 为 0,只表示数据不需要继续为 Time Travel 保留,不能据此判断 p3 会立即从计费存储中消失。

如果 T2 是永久表,相关数据还可能进入 Fail-safe。在删除后的一段时间里,p3 仍可能体现在 FAILSAFE_BYTES 中。如果把这部分计入实际存储,存储量可能暂时仍接近:

[ 17+5=22\text{ MB} ]

如果 T2 是 transient table,则不会出现与永久表相同的 Fail-safe 行为,但物理回收和统计视图更新仍可能异步完成。

17 MB 是去重后的物理数据集合,不是表逻辑大小之和

删除 T2 后,存活表的逻辑大小之和仍为:

[ T1+T3=10+12=22\text{ MB} ]

由于 p1 被两张表共享,去重后的结果才是:

[ 22-5=17\text{ MB} ]

所以,“剩余表的逻辑大小”和“clone group 的实际唯一存储量”是两个不同的指标。

后续 DML 会改变结果

如果 T1 或 T3 执行 UPDATE、DELETE、MERGE 等操作,Snowflake 可能生成新的 micro-partitions。旧版本也可能因为 Time Travel、Fail-safe 或其他 clone 的引用而继续保留,此时不能再沿用固定的 17 MB 结论。

17 MB 成立需要满足以下全部条件:

  • 分区关系与题设一致;
  • T2 已删除;
  • p3 没有被其他 clone 或表引用;
  • p3 已不处于 Time Travel 或 Fail-safe 保留状态;
  • 后台清理已经完成;
  • T1、T3 没有产生新的数据版本。

备注:内容仅供参考。