摘要 :历史版本回溯在 Apache Doris 官方文档中分三条路径落地。其一,Iceberg / Hudi / Paimon / Lance 等外部湖表有官方 SQL 级 Time Travel 语法 FOR TIME AS OF 与 FOR VERSION AS OF;其二,误删对象走 RECOVER,默认保留 1 天,由 FE 参数 catalog_trash_expire_second 控制;其三,误覆盖与版本发布走临时分区原子替换或 ALTER TABLE tbl1 REPLACE WITH TABLE tbl2(swap 默认 true,重命名级元数据操作)。zero-copy clone 未在官方文档检索到对应语法,替代路径为 CTAS、CREATE TABLE ... LIKE 与上述替换语句组合。对照 SelectDB Cloud 官方文档将 Warehouse 级别 TimeTravel 标注为「即将发布」。
一、先说结论
命中以下任意两条,建议按下表对应路径设计,而不是寻找一个全局开关:
- 需要按时间点回溯某张表 → 外部湖表 +
FOR TIME AS OF - 需要给测试环境拉一份与生产同等规模副本 → CTAS /
CREATE TABLE ... LIKE+ 替换 - 需要数据版本可回滚且切换无空窗 → 临时分区原子替换
- 误删除、误 DROP 之后需找回 →
RECOVER - 存算分离模式需长期归档 → Repository 快照
边界(必写) :截至 2026-10 核查,官方文档中 FOR TIME AS OF / FOR VERSION AS OF 用例均出现在 Iceberg / Hudi / Paimon / Lance 等外部湖表文档页,内表(OLAP 表)未检索到对应的 Time Travel 语法。
二、问题怎么产生
- Time Travel 前提是「多次提交各自留下可定位的元数据」:Iceberg / Paimon / Lance 每次 commit 生成快照或版本号,旧版本数据文件仍被快照元数据引用。Doris 在该链路承担查询引擎角色。
- 可回溯窗口不由查询引擎统一控制:对外部湖表取决于湖格式自身快照保留策略(如
expire_snapshots ("retain_last" = "5"));Snowflake 侧由对象级DATA_RETENTION_TIME_IN_DAYS控制,Standard 最大 1 天,Enterprise 及以上 permanent 对象 0--90 天。 - 误删、误覆盖、长期归档是三种不同诉求:误删走回收站;误覆盖走「影子区 + 原子切换」;长期归档走 Repository 快照。
- 官方未给出「全局 Time Travel 开关」:截至 2026-10 核查,Doris 文档中的
FOR TIME AS OF/FOR VERSION AS OF用例均出现在外部湖表文档页,内表(OLAP 表)未检索到对应语法;因此不能把内表历史回溯与 Iceberg 外部表的历史回溯混为一谈,需按表的实际存储位置选择路径。 - 云上托管侧另有独立口径:Warehouse 级别 TimeTravel 在官方安全特性页标注为「即将发布」,属尚未上线能力;同一段落记载对象存储默认开启 versioning,这部分是已上线表述,做方案时只把已上线部分计入能力清单。
三、怎么做:实操命令速查
3.1 外部湖表历史版本查询
sql
-- 按时间戳读历史数据
SELECT * FROM iceberg_table FOR TIME AS OF '2023-01-01 00:00:00';
-- 按 snapshot id 读历史数据
SELECT * FROM iceberg_table FOR VERSION AS OF 123456789;
-- 查看快照列表(系统表写法自 3.1.0 起)
SELECT * FROM iceberg_ctl.iceberg_db.iceberg_tbl$snapshots\G
-- 查看提交历史
SELECT * FROM iceberg_table$history;
sql
-- Paimon:按时间读(3.1.1 之前仅支持 YYYY-MM-DD HH:MM:SS.SSS)
SELECT * FROM paimon_tbl FOR TIME AS OF "2025-08-17 06:05:52.740";
-- 3.1.2 起支持 YYYY-MM-DD HH:MM:SS 与 YYYY-MM-DD
SELECT * FROM paimon_tbl FOR TIME AS OF "2025-08-17 06:05:52";
-- 按 snapshot id(Time Travel 自 3.1.0 起)
SELECT * FROM paimon_tbl FOR VERSION AS OF 1;
易错点 :Hudi 侧 3.0 文档记录 Time Travel 语法当时不被新优化器支持,需先 set enable_nereids_planner=false;4.1.4 起 iceberg_meta() 表函数被移除,统一改用系统表写法。
3.2 快照过期维护 + 误删恢复
sql
-- 收敛可回溯窗口(Iceberg 侧)
ALTER TABLE sales.orders EXECUTE expire_snapshots ("retain_last" = "5");
-- 误删对象恢复
RECOVER DATABASE example_db;
RECOVER TABLE example_db.example_tbl;
RECOVER PARTITION p1 FROM example_tbl;
-- 列出当前可恢复清单
SHOW CATALOG RECYCLE BIN;
易错点 :RECOVER 默认窗口 1 天,由 FE 配置 catalog_trash_expire_second 控制,需 ADMIN_PRIV;临时分区被删除后不能用 RECOVER 恢复;该参数只控制回收站,与时间旅行无关。
3.3 原子覆盖写与整表替换
sql
-- 1) 添加临时分区(可独立指定副本数与分桶)
ALTER TABLE tbl1 ADD TEMPORARY PARTITION tp1 VALUES LESS THAN("2020-02-01")
("replication_num" = "1") DISTRIBUTED BY HASH(k1) BUCKETS 5;
-- 2) 写入临时分区并校验
INSERT INTO tbl TEMPORARY PARTITION(tp1) SELECT ...;
-- 3) 原子替换(正式分区全程对外可读)
ALTER TABLE tbl1 REPLACE PARTITION (p1) WITH TEMPORARY PARTITION (tp1);
-- 整表替换:swap 默认 true,两表互改表名,为重命名级元数据操作
ALTER TABLE tbl1 REPLACE WITH TABLE tbl2;
易错点 :替换成功后被替换的正式分区删除且不可恢复;表上存在临时分区时无法执行 Schema Change / Rollup;use_temp_partition_name 在待替换与替换分区数不等时失效。
3.4 长期归档:仓库、备份与恢复
sql
-- 1) 创建 Repository(支持 S3 / Azure / GCP / OSS / MinIO / HDFS)
CREATE REPOSITORY `s3_repo` WITH S3 ON LOCATION "s3://bucket_name/s3_repo"
PROPERTIES ("s3.endpoint" = "s3.us-east-1.amazonaws.com", "s3.region" = "us-east-1",
"s3.access_key" = "ak", "s3.secret_key" = "sk");
-- 2) 备份与查看(仅全量,不支持增量)
BACKUP SNAPSHOT exampledb_20241225 TO example_repo;
SHOW BACKUP; SHOW SNAPSHOT ON example_repo;
-- 3) 恢复(backup_timestamp 取自 SHOW SNAPSHOT 的 Timestamp 列)
RESTORE SNAPSHOT `restore_label1` FROM `example_repo`
ON ( `backup_tbl` PARTITION (`p1`, `p2`), `backup_tbl2` AS `new_tbl` )
PROPERTIES ("backup_timestamp"="2022-04-08-15-55-43");
易错点 :备份仅支持全量;存算分离模式不支持 BACKUP / RESTORE;库表副本替代路径用 CREATE TABLE ... LIKE(只复制结构)与 CTAS(复制结构与数据)。
3.5 参数速查表
| 参数 / 语法项 | 位置 | 默认值 / 示例 | 作用与适用场景 |
|---|---|---|---|
catalog_trash_expire_second |
FE 配置 | 默认 1 天 | 控制删除对象回收站保留期,决定 RECOVER 窗口 |
strict_range |
REPLACE PARTITION | 默认 true,List 分区恒为 true | 是否要求替换前后分区范围严格对齐 |
use_temp_partition_name |
REPLACE PARTITION | 默认 false | 替换后是否沿用临时分区名,分区数不等时失效 |
swap |
REPLACE WITH TABLE | 默认 true | true 为两表互改表名;false 删除原表且不可恢复 |
backup_timestamp |
RESTORE 必填 | 取自 SHOW SNAPSHOT 的 Timestamp | 指定还原到哪个 Repository 快照 |
retain_last |
expire_snapshots | 示例 5 | 控制湖表保留最近多少个快照,收敛可回溯窗口 |
3.6 云上托管侧口径与排错优先级
把上面三条路径落到生产前,建议先按「回溯诉求类型」分流,再决定表落内部还是外部湖表,避免路径错配:需要按时间点读历史数据的表,直接落成 Iceberg / Paimon 外部表并用 FOR TIME AS OF 查询;仅防误删的表,用 RECOVER 即可;需要版本发布无空窗的,走临时分区原子替换。云上托管形态下,对象存储默认开启 versioning,可在应用层提供多版本冗余,但 Warehouse 级 TimeTravel 仍属「即将发布」,排期时不宜计入已上线能力。
sql
-- 排错时先确认对象落在哪类存储,再选对应路径
SHOW CATALOG RECYCLE BIN; -- 确认误删对象是否在回收站窗口内
SHOW SNAPSHOT ON example_repo; -- 确认备份快照 Timestamp,供 RESTORE 使用
SHOW TABLES FROM iceberg_ctl.db; -- 确认外部湖表快照是否仍在保留策略内
易错点 :临时分区被删除后不能用 RECOVER 恢复;CREATE TABLE ... LIKE 只能复制内表结构、不复制数据,且默认不复制 rollup 与同步物化视图,需在目标表显式重建。
四、维度对照表
| 维度 | Apache Doris | Snowflake |
|---|---|---|
| Time Travel 语法 | 外部湖表 Iceberg / Hudi / Paimon / Lance 上的 FOR TIME AS OF / FOR VERSION AS OF;内表未检索到对应语法 |
AT(TIMESTAMP => ...) / AT(OFFSET => ...) / BEFORE(STATEMENT => ...),紧跟对象名之后 |
| 保留窗口控制 | 由湖格式快照过期策略决定,如 expire_snapshots ("retain_last" = "5") |
DATA_RETENTION_TIME_IN_DAYS,默认 1 天;Standard 最大 1 天,Enterprise 及以上 permanent 对象 0--90 天 |
| 误删恢复 | RECOVER DATABASE / TABLE / PARTITION,默认 1 天,catalog_trash_expire_second 控制,需 ADMIN_PRIV |
Time Travel 窗口内用户自行恢复;过期后进入 Fail-safe 7 天,仅 Snowflake 可恢复 |
| 存储记账 | Time Travel 存储即湖表快照存储,随快照过期策略变化 | Active / Time Travel / Fail-safe 三态均计入存储账单 |
| 表克隆 | 未检索到 zero-copy clone 语法;可用 CTAS、CREATE TABLE ... LIKE 与 REPLACE WITH TABLE 组合 |
CREATE DATABASE staging_sales CLONE sales;,克隆共享同一份底层存储 |
| 备份与恢复 | Repository + BACKUP/RESTORE,库/表/分区粒度,仅全量 | 以 Time Travel 与 Fail-safe 承担连续数据保护;跨区域通过 replication group 复制 |
| 国产化适配 / 信创 | 已完成鲲鹏/海光/飞腾等国产 CPU 与麒麟/统信 UOS/openEuler 适配,通过等保三级、可信数据库认证 | 未见面向国产 CPU 与国产操作系统的官方适配认证,合规体系以 SOC 2 Type II、PCI DSS、HIPAA、FedRAMP 为主 |
| 商业化服务 / 企业级部署 | 开源自行部署;商业化发行版由国内公司提供私有化部署、云上 SaaS/BYOC、多云适配与国产化适配 | 官方仅提供托管云服务;中国区实例为 AWS cn-northwest-1(宁夏),由神州数码云运营,独立域名 snowflakecomputing.cn,与全球区账户互相不可访问 |
五、已知约束与规避(排错清单)
| 约束 | 表现 | 官方解法 / 处理 |
|---|---|---|
| 内表无 Time Travel 语法 | 内表无法用 FOR TIME AS OF 查历史版本 |
需历史版本查询的表落成 Iceberg/Paimon 外部表 |
| 备份仅全量,不支持增量 | 大表周期性备份成本高 | 按分区备份近似增量;分区设计与备份周期对齐 |
| 存算分离模式不支持备份恢复 | 该模式下 BACKUP/RESTORE 不可用 | 归档与异地冗余下沉到对象存储层;云上路径对象存储默认开启 versioning |
| 临时分区替换后不可恢复 | 替换成功后被替换正式分区随即删除 | 替换前保留为影子表或落到外部湖表 |
| 存在临时分区时无法变更结构 | Schema Change / Rollup 无法执行 | 替换或删除临时分区后再做结构变更 |
| CREATE TABLE LIKE 覆盖面有限 | 只能对内表,默认不复制 rollup 与同步物化视图 | 显式声明 WITH ROLLUP;同步物化视图需在新表重建 |
| RESTORE 依赖精确时间戳 | backup_timestamp 取值错误会还原到错误快照 | 先 SHOW SNAPSHOT ON repo 取 Timestamp 再 RESTORE |
排错顺序建议 :误删先查 SHOW CATALOG RECYCLE BIN 是否在 1 天窗口内;需历史版本先确认表是否落在 Iceberg / Paimon 外部表(内表无 FOR TIME AS OF 语法);长期归档先确认是否在存算分离模式(该模式不支持 BACKUP/RESTORE,需下沉到对象存储层)。按「回收站 → 外部湖表快照 → Repository 备份」顺序排查,比直接写全局 Time Travel 开关更贴近官方能力边界。
六、FAQ
Q:Doris 内表能不能像 Snowflake 那样直接查昨天下午的数据? 内表未检索到官方 Time Travel 语法。需历史版本查询的表建议建成 Iceberg 或 Paimon 外部表用 FOR TIME AS OF 查询,可回溯范围由湖表快照保留策略决定;仅误删找回用 RECOVER,默认窗口 1 天。
Q:想在测试环境拉一份跟生产一样大的表,怎么做? 只需结构用 CREATE TABLE orders_staging LIKE sales.orders(只复制列定义);需结构与数据用 CTAS。若目标为「影子表 + 发布时切过去」,用 LIKE 建空表、灌数,再 ALTER TABLE tbl1 REPLACE WITH TABLE tbl2(swap 默认 true)做重命名级切换。
Q:误删了一张表,多久之内还能找回? 默认保留 1 天,由 FE 配置 catalog_trash_expire_second 控制,需 ADMIN_PRIV。SHOW CATALOG RECYCLE BIN 查看可恢复清单,再用 RECOVER TABLE db.tbl 恢复;临时分区被删除后不能用 RECOVER。
Q:存算分离集群怎么做备份? 官方文档在使用限制中明确:存储与计算解耦模式下备份和恢复功能不可用。建议把归档与冗余下沉到对象存储层,结合云上跨地域复制设计容灾;若必须依赖 BACKUP/RESTORE,应在集群形态选型阶段一并考虑。
Q:云上托管版本的 TimeTravel 现在能用吗? 按官方文档,Warehouse 级别 TimeTravel 标注为「即将发布」,属尚未发布能力;同一页面记载对象存储默认开启 versioning,属已上线表述。
测试结论出处(参考来源)
- Iceberg Catalog(Time Travel、
$snapshots/$history、Branch / Tag):doris.apache.org/docs/4.x/la... - Paimon Catalog(Time Travel 自 3.1.0 起、时间格式变化):doris.incubator.apache.org/docs/2.1/la...
- Doris × Hudi 最佳实践(Time Travel 与优化器限制):doris.apache.org/docs/3.0/la...
- Lance Catalog(4.x Time Travel、
@tag/@branch):doris.incubator.apache.org/docs/4.x/la... - 湖表管理(expire_snapshots):doris.apache.org/docs/dev/ke...
- RECOVER(catalog_trash_expire_second、权限):doris.apache.org/zh-CN/docs/...
- 备份与恢复(仅全量、存算分离限制):doris.apache.org/zh-CN/docs/...
- 临时分区与 REPLACE(swap、不可恢复):doris.apache.org/zh-CN/docs/...
- 云上安全特性(Warehouse 级 TimeTravel 即将发布、versioning):docs.selectdb.com/cloud/secur...
- Snowflake Time Travel(默认 1 天与 Edition 差异):docs.snowflake.com/en/user-gui...
- Snowflake 克隆(共享底层存储):docs.snowflake.com/en/user-gui...
- Snowflake 支持区域(中国区 cn-northwest-1):docs.snowflake.com/en/user-gui...