4. 快照核心概念
在 Iceberg 中,快照(Snapshot)是表在某一时刻的完整数据状态描述。它不是把整张表的数据复制一份,而是记录“当前表由哪些数据文件、删除文件、清单文件组成”的元数据视图。理解快照,是掌握 Time Travel、版本回溯、增量读取和并发写入控制的基础。
一、什么是快照:表状态的时间切片
可以把 Iceberg 表想象成一本不断修订的书。每次写入、删除、更新或压缩,都会产生一个新的“修订版本”,这个修订版本就是快照。快照中主要包含:
- 快照 ID:该快照的唯一标识,通常是一个长整型数字。
- 父快照 ID:指向上一个快照,形成版本链。
- 时间戳:快照创建时间,用于按时间回溯。
- 清单列表(Manifest List):描述本次快照包含哪些清单文件。
- 摘要信息:如新增文件数、删除文件数、总记录数等统计信息。
因此,快照是“元数据层面的状态切片”,而不是“物理数据的全量拷贝”。这也是 Iceberg 能够低成本支持 Time Travel 的关键原因。
二、快照的生成时机
快照不是随时都会产生,而是在表状态发生“提交级变化”时生成。常见触发场景包括:
- 追加写入:INSERT、流式写入新增数据文件,生成新快照。
- 删除与更新:DELETE、UPDATE、MERGE 产生删除文件或重写数据文件,生成新快照。
- 模式演进:新增列、改列类型等元数据变更,通常也会伴随新快照或新元数据版本。
- 压缩与重写:Compaction、Rewrite Data Files 优化小文件,生成新快照。
- 分区演进:分区策略变化后,新数据按新分区写入,形成新快照。
三、快照 ID、父快照与版本链
快照 ID 是快照的唯一主键。父快照 ID 则把快照串成一条链:
Snapshot S1 (id=1001, parent=null)
└── Snapshot S2 (id=1002, parent=1001)
└── Snapshot S3 (id=1003, parent=1002)
└── Snapshot S4 (id=1004, parent=1003)
这条链就是版本回溯的“路线图”。当执行 Time Travel 时,Iceberg 会根据指定的 snapshot-id 或 timestamp 找到目标快照,然后读取该快照对应的清单列表和数据文件。父快照的存在,使得增量读取、变更日志和审计追踪成为可能。
四、快照生命周期与元数据版本
快照生命周期通常包括:创建、生效、保留、过期、清理。元数据版本则记录表结构、分区、快照列表等全局信息。两者关系如下表:
| 概念 | 作用 | 是否可回溯 | 典型操作 |
|---|---|---|---|
| 快照 Snapshot | 记录某一时刻的数据文件集合 | 是,按 ID 或时间 | Time Travel、增量读取 |
| 父快照 Parent Snapshot | 形成版本链,支持差异计算 | 是,沿链回溯 | 审计、变更追踪 |
| 元数据版本 metadata.json | 记录表结构、快照列表、当前快照 | 是,保留历史版本 | 表恢复、模式演进 |
| 过期快照 Expired Snapshot | 释放不再需要的元数据与文件引用 | 否,清理后不可回溯 | expire_snapshots |
五、实战场景:按快照回溯与清理
假设需要查看表在某个快照时的数据,可以使用 snapshot-id 查询:
-- Spark SQL 示例
SELECT * FROM demo.db.orders VERSION AS OF 1002;
-- 按时间回溯
SELECT * FROM demo.db.orders TIMESTAMP AS OF '2025-01-01 10:00:00';
查看快照历史:
SELECT snapshot_id, parent_id, committed_at, operation
FROM demo.db.orders.snapshots
ORDER BY committed_at;
清理过期快照:
CALL demo.system.expire_snapshots(
table => 'db.orders',
older_than => TIMESTAMP '2025-01-01 00:00:00',
retain_last => 5
);
这段配置表示:保留最近 5 个快照,并清理早于指定时间的快照。执行后,旧快照不再可回溯,但被引用的数据文件仍可能因其他快照而保留。
六、复盘要点
- 快照是元数据状态,不是数据拷贝;Time Travel 的本质是切换快照引用。
- 快照 ID 唯一标识版本,父快照 ID 构成版本链,元数据版本记录当前指向。
- 写入、删除、更新、压缩、模式演进等提交动作都会生成新快照。
- 快照过期不等于数据文件立即删除,需结合文件引用和保留策略判断。
- 生产环境应明确 Time Travel 保留窗口,避免误清理导致无法回溯。
掌握快照、快照 ID、父快照、生命周期与元数据版本之间的关系,就掌握了 Iceberg 版本回溯的底层逻辑。后续无论是做增量同步、审计追踪还是故障恢复,都可以围绕“找到目标快照,读取其清单,定位数据文件”这条主线展开。