
Apache Iceberg 的 branch 和 tag 是用于快照(snapshot)的逻辑标记机制,本身不创建新数据,而是对已有快照的引用。它们不等同于 Git 的分支或标签,不能直接“提交”变更,但能有效支持版本管理与安全回滚。
branch 与 tag 的核心区别
branch 是可移动的引用,常用于开发、测试或发布流程中指向某个快照,并允许后续更新(如合并新快照);tag 是不可变的引用,一旦创建就固定指向某个快照,适合标记生产发布点(如 v1.2.0)、审计锚点或回滚基准。
- branch 可通过
set current snapshot或rewrite manifest等操作更新其指向 - tag 创建后无法修改,删除后也不能恢复原引用(除非重新创建)
- 两者都不复制数据,仅增加元数据中的引用记录,开销极小
用 SQL 创建和查看 branch/tag
Iceberg 0.14+ 支持标准 SQL 语法管理这些引用(需引擎支持,如 Trino 417+、Spark 3.4+ with Iceberg 1.4+):
- 创建 branch:
CALL system.create_branch('my_table', 'dev', 987654321)(指定快照 ID) - 创建 tag:
CALL system.create_tag('my_table', 'v1.0.0', 987654321) - 查看所有引用:
SELECT * FROM my_table.refs(返回 name、type、snapshot_id、max_ref_age_ms 等字段) - 查某 branch 当前快照:
SELECT snapshot_id FROM my_table.refs WHERE name = 'dev' AND type = 'branch'
基于 branch/tag 的安全回滚操作
回滚本质是将表的 current_snapshot_id 重置为某个历史快照 —— 最稳妥方式是先用 tag 锚定目标版本,再切换:
- 若已存在 tag(如
v1.0.0),执行:CALL system.rollback_to_tag('my_table', 'v1.0.0') - 若只有 branch(如
prod-stable),可用:CALL system.rollback_to_branch('my_table', 'prod-stable') - 若只知道快照 ID,可先建临时 tag 再回滚:
CALL system.create_tag('my_table', 'tmp-rollback', 123456789); CALL system.rollback_to_tag('my_table', 'tmp-rollback') - 回滚后,原 current 快照仍保留在元数据中,未被删除,可再次 forward(只要没触发过 expire_snapshots)
注意事项与常见陷阱
branch/tag 管理依赖元数据一致性,实际使用中需注意:
- 并发写入时,branch 更新可能冲突(如两个作业同时 set 同一分支),建议配合应用层锁或幂等逻辑
- tag 不会阻止快照过期;若未配置保留策略,
expire_snapshots可能删掉 tag 指向的快照 → 回滚失败。务必设置history.expire.max-snapshot-age-ms或手动保护关键快照 - Trino 中读取时默认查 current 快照;要查 branch/tag 对应数据,需显式指定:
SELECT * FROM my_table.branch_dev或SELECT * FROM my_table.tag_v1.0.0 - Spark SQL 不支持
.branch_xxx语法,需用spark.read.format("iceberg").option("branch", "dev").load("my_table")










