Time Travel

HologresV4.0版本开始支持Time Travel功能,开启该功能后,可记录数据每次变更(INSERT、DELETE、UPDATE、INSERT OVERWRITE等)的历史版本,支持在指定时间范围内查询任意时间点历史数据(即已更新或删除的数据)。通过Time Travel功能您可以分析指定时间段内数据的使用情况、恢复误删除或更新前的数据,避免业务损失。

使用限制

  • Hologres V4.0及以上版本支持该功能。如果您的实例是V4.0以下版本请参见实例升级

  • Hologres内部表、Dynamic Table支持使用Time Travel。

    说明

    外部表的Time Travel查询见基于DLF访问Paimon Catalog

使用说明

设置Time Travel

  • 语法:

    Time Travel是表级别的属性,需要在建表时设置如下两个属性:

    CREATE TABLE <table_name> (...)
    WITH (
        enable_mvcc = 'true|false',
        mvcc_gc_ttl_seconds = '<num>'
    );
  • 使用说明

    • 已有表不支持设置上述参数,必须新建表时设置。

    • 开启Time Travel后,表会保存多个版本的数据,会有额外的存储增加。

    • 开启Time Travel后,查询时可能会有一定的性能损失。

  • 参数说明

    参数名称

    描述

    enable_mvcc

    是否开启Time Travel功能,取值如下:

    • true:开启,Time Travel开启后,不支持关闭。

    • false(默认值):关闭。

    mvcc_gc_ttl_seconds

    开启Time Travel后,每个数据版本保留的时长,单位为秒(s)。

    • 默认值为1天=24*3600 s=86400 s。

    • 最小值为0:不表示关闭Time Travel,而是表示在0 s后会回收版本的数据,无法查询。

    说明

    查询超过Time Travel保留的TTL时间范围时,系统会在后台不定期删除保留的版本数据,查询时会报错,示例报错Tablexxx only supports time traveling between xxx and xxx;

通过Time Travel查询数据

开启Time Travel后,可以在TTL范围内,可以使用FOR TIMESTAMP AS OF语法查询某个时间点的数据,语法如下:

SELECT * FROM {table_name} FOR TIMESTAMP AS OF (now() - interval '1 hour');
SELECT * FROM {table_name} FOR TIMESTAMP AS OF '2025-08-05 11:18:50+08';
SELECT * FROM {table_name} FOR TIMESTAMP AS OF 1754374966;

修改Time TravelTTL

可以根据业务情况修改Time TravelTTL,语法如下:

ALTER TABLE {table_name} SET (mvcc_gc_ttl_seconds =<num>);

修改TTL的行为说明如下:

  • TTL从大的值变更为小的值时:系统会在后台根据新TTL值删除过期的版本数据,超过TTL的版本数据查询会报错。

  • TTL从小的值变更为大的值时:会导致之前已经删除了在TTL范围内的版本记录,已经删除的无法恢复,会导致查询不准确。因此,不建议生产中讲TTL从小值变更为大的值。

使用示例

  1. 创建表并开启Time Travel。

    BEGIN;
    CREATE TABLE test1 (
        a int NOT NULL PRIMARY KEY,
        b int,
        c int
    )
    WITH (
        enable_mvcc = TRUE,
        mvcc_gc_ttl_seconds = 864000
    );
    COMMIT;
    
    --插入数据
    INSERT INTO test1 VALUES (1, 2, 3);
  2. 通过Time Travel查询数据。

    SELECT * FROM test1 FOR TIMESTAMP AS OF now();

    返回结果如下。

    a	b	c
    ------
    1	2	3
    
  3. 更新表并通过Time Travel查询。

    INSERT INTO test1 (a, b, c) VALUES (1, 4, 5)
    ON CONFLICT (a)
    DO UPDATE SET b = EXCLUDED.b;
    
    SELECT * FROM test1 FOR TIMESTAMP AS OF (now() - interval '1 minute');

    返回结果如下。

    a	b	c
    ------
    1	4	5