iceberg 的 branch 可写、支持动态更新与保留策略,用于协作开发;tag 只读、不可变、强制保留快照,用于标记稳定状态;二者均通过 alter table 创建,查询时用 at 子句指定,名称均区分大小写。

Iceberg 的 branch 和 tag 都用于管理表的历史快照,但设计目标和使用场景不同:branch 侧重可变的、协作式开发流程(如测试、灰度发布),tag 则用于标记不可变的稳定状态(如生产发布、审计点)。
branch 支持写入与动态更新
branch 是可写的引用,允许向其提交新的快照。例如,在上线前验证新数据逻辑时,可创建 dev-2024-q3 分支,持续追加测试数据,再通过 cherry-pick 或合并方式将确认无误的快照合入主分支(main)。系统会自动维护该分支的最新快照 ID,并支持设置保留策略(如最多保留 7 天或 5 个快照)。
- 可通过
ALTER TABLE ... CREATE BRANCH创建 - 支持
INSERT INTO ... TO BRANCH写入 - 可被
SET CURRENT BRANCH设为默认读写目标 - 删除分支不删除底层文件,仅移除引用
tag 仅指向固定快照,不可修改
tag 是只读的命名指针,一旦创建就永久绑定到某个快照 ID,即使该快照后续被过期清理,tag 本身仍存在(但查询会失败)。典型用途包括标记上线版本(v2.1.0)、合规检查时间点(audit-20240930)或数据回溯基线。
- 用
ALTER TABLE ... CREATE TAG创建,必须指定快照 ID 或时间戳 - 不支持写入,无法通过 SQL 向 tag 插入数据
- 删除 tag 仅移除命名引用,不影响快照生命周期
- 可通过
REFS系统表查看所有 tag 及对应快照信息
快照生命周期管理逻辑不同
branch 的快照受 TTL(time-to-live)和最小快照数策略约束,旧快照可能被自动清理;而 tag 所指向的快照会被强制保留——只要 tag 存在,对应快照就不会被 expire_snapshots 清理。这意味着 tag 是一种“保留锁”,适合需要长期存档的场景。
- branch 的保留策略由
write.branch.max-ref-age-ms等配置控制 - tag 不参与自动清理,需手动
DROP TAG才能解除保留 - 一个快照可同时被多个 branch 和 tag 引用
读取时的行为差异
查询时可通过 AT 子句指定 branch 或 tag 名称,例如 SELECT * FROM tbl AT BRANCH 'dev' 或 SELECT * FROM tbl AT TAG 'v2.0'。注意:tag 查询始终返回创建时那一刻的完整快照;branch 查询则返回该分支当前指向的最新快照,可能随写入变化。
- 未指定时,默认读取
main分支的最新快照 - branch 名称区分大小写,tag 名称也区分大小写
- Flink / Spark 连接器均支持
AT语法,但需 Iceberg 0.14+ 版本










