首批通过分布式安全可靠测评,为关键业务系统打造
使用 TTL(Time To Live)功能
更新时间:2026-07-02 12:27:01
OceanBase 数据库 SQL 模式下的 TTL(Time To Live)功能提供了过期数据的管理能力。通过对表定义 TTL 策略来设置数据的有效期,再由系统执行过期数据(TTL)任务处理已过期的数据。
对于定义了 TTL 策略的表,系统对过期数据的处理主要分为以下两步:
当 TTL 任务被触发时,具有 TTL 属性的表及其索引表、辅助表会通过事务同步一个标记删除的规则信息,满足规则的数据行会被标记为删除,数据被标记删除后就会对用户不可见。
对于标记删除的数据,在下次执行 Compaction(合并)时,系统会将数据从存储层彻底删除,以便释放存储空间。
本文主要介绍如何通过命令或者设置周期性任务两种方式来发起过期数据(TTL)任务。
注意事项
在 TTL 任务同步标记删除信息时,会对表加锁,与旁路导入、DDL、Transfer 等操作互斥。
当主表、索引表、辅助表等所有分区数超过 4000 时,可能会发生事务超时,导致标记删除信息的任务一直失败重试,可以通过调大超时时间解决,语句如下。
obclient(root@sys)[(none)]> ALTER SYSTEM SET internal_sql_execute_timeout = 600; /*sys 租户下执行,单位为秒*/由于标记删除信息的事务与普通 DML 事务不互斥,当两个事务并发且事务隔离级为 Read Committed,在 DML 事务内查询临近过期的数据时,可能会遇到幻读。
例如,假设有一个标记删除信息的事务
trans_A和一个普通 DML 事务trans_B,以及临近过期的数据行rowkey_A,在 T1 ~ T3(T1 < T2 < T3)这段时间内:- 在 T1 时间点:数据行
rowkey_A未达到过期时间,普通 DML 事务trans_B可以读取到rowkey_A的数据。 - 在 T2 时间点:数据行
rowkey_A达到过期时间,标记删除信息的事务trans_A将rowkey_A标记为删除。 - 在 T3 时间点:普通 DML 事务
trans_B再次读取rowkey_A,发现已读取不到该数据。
- 在 T1 时间点:数据行
当 TTL 任务未执行时,用户可以查询到表中符合过期规则的数据,若用户对过期数据有严格的可见性要求,需要在查询 SQL 中添加过滤条件。
在主表及其索引上执行 Offline DDL、新建索引的操作后,表数据会被重写,数据的写入时间会被更新,使得数据过期延迟。
执行 TTL 任务后,过期数据会在 Compaction(合并)过程中异步删除,删除过期数据的过程仅在 OceanBase 数据库内部进行,不会同步给下游的其他应用系统。
TTL 表的定义
使用限制
使用 TTL 功能进行过期数据的管理时,对 TTL 表有以下限制:
不支持外键约束。
不支持触发器。
不支持向量索引、全文索引。
仅支持 TTL 列为单列,不支持 TTL 列为虚拟列、生成列、表达式。
不支持表更新模式
MERGE_ENGINE为partial_update。当前版本仅支持 TTL 列为内部隐藏列
ora_rowscn(记录最后一次更新的时间戳)。定义了 TTL 属性的表,不允许添加列名为
ora_rowscn的列。
创建具有 TTL 属性的表
创建 TTL 表的语句如下:
CREATE TABLE table_name (table_definition_list) MERGE_ENGINE = {append_only | delete_insert}
TTL [=] col_name + INTERVAL interval_num ttl_unit BY COMPACTION;
语句中相关参数说明如下:
MERGE_ENGINE:指定表的更新模式。当前不支持表更新模式MERGE_ENGINE为partial_update。col_name:指定 TTL 过滤列。当前版本仅支持指定列名为ora_rowscn(内部隐藏列,记录数据最后一次更新的时间戳)。interval_num:指定过期时间的整数数值,取值范围 [0,+∞)。值为0时,时间单位ttl_unit可以为取值中的任意值,表示数据一旦提交即过期。ttl_unit:指定过期时间的单位。取值支持SECOND、MINUTE、HOUR、DAY、MONTH或YEAR。
例如,创建一个数据过期时间为 7 天的 TTL 表。
obclient> CREATE TABLE ttl_tbl1(
id INT PRIMARY KEY,
val VARCHAR(100)
) MERGE_ENGINE = append_only TTL ora_rowscn + INTERVAL 7 DAY BY COMPACTION;
TTL 表创建成功后,可以根据业务实际情况,修改表的 TTL 策略,语句如下:
obclient> ALTER TABLE ttl_tbl1 SET TTL ora_rowscn + INTERVAL 1 HOUR BY COMPACTION;
同样,如果不再需要使用 TTL 功能,可以删除表的 TTL 策略,语句如下。
obclient> ALTER TABLE ttl_tbl1 REMOVE TTL;
TTL 任务的触发
对于每一张定义了 TTL 属性的表,在开启 TTL 功能的情况下,系统内部会定期调度 TTL 任务来处理已过期的数据。执行 TTL 任务后,超过有效期的数据将会不可见,但是数据实际并未删除,过期数据会在 Compaction(合并)过程中异步删除(不占用 clog 和写入带宽)。待 Compaction(合并)任务执行后,过期数据占用的存储空间才会真正释放。
开启 TTL 功能
发起 TTL 任务要求当前租户已开启 TTL 功能。TTL 功能的开关由租户级配置项 [enable_ttl](../../800.configuration-items-and-system-variables/100.system-configuration-items/400.tenant-level-configuration-items/3020.enable_ttl.md)(值为 True)控制,该配置项在新建租户、恢复租户的场景下其默认值均为 False,需要用户手动开启。
管理员用户登录到集群的
sys租户或用户租户。连接示例如下,连接数据库时请以实际环境为准。
obclient -h10.xx.xx.xx -P2883 -uroot@mysqltenant#obdemo -p***** -A执行以下语句,开启 TTL 功能。
系统租户为指定租户开启 TTL 功能。
obclient(root@sys)[(none)]> ALTER SYSTEM SET enable_ttl = True TENANT = tenant_name;用户租户为本租户开启 TTL 功能。
obclient> ALTER SYSTEM SET enable_ttl = True;
配置定时触发 TTL 任务的时间
开启 TTL 功能后,系统会根据租户下 TTL 表的数据过期情况,定时触发 TTL 任务。定时触发 TTL 任务的时间通过租户级配置项 ttl_duty_time 控制,默认触发时间为每天的凌晨 01:00。
ttl_duty_time 的时刻点与租户的时区相同,建议设置在租户的业务低峰期、租户每日合并发起之前。例如,修改为凌晨 02:00。
修改定时触发时间的操作如下:
管理员用户登录到集群的
sys租户或用户租户。连接示例如下,连接数据库时请以实际环境为准。
obclient -h10.xx.xx.xx -P2883 -uroot@mysqltenant#obdemo -p***** -A执行以下语句,修改 TTL 任务的定时触发 TTL 任务的时间。
系统租户为指定租户修改定时触发 TTL 任务的时间。
obclient(root@sys)[(none)]> ALTER SYSTEM SET ttl_duty_time = '02:00' TENANT = tenant_name;用户租户为本租户修改定时触发 TTL 任务的时间。
obclient> ALTER SYSTEM SET ttl_duty_time = '02:00';
手动触发 TTL 任务
开启 TTL 功能后,用户可以手动触发一次 TTL 任务。
管理员用户登录到集群的
sys租户或用户租户。连接示例如下,连接数据库时请以实际环境为准。
obclient -h10.xx.xx.xx -P2883 -uroot@sys#obdemo -p***** -A执行以下命令,手动触发一次 TTL 任务。
系统租户为所有用户租户手动触发一次 TTL 任务。
obclient(root@sys)[(none)]> ALTER SYSTEM TRIGGER TTL TENANT = all_user;注意
不支持系统租户通过
ALTER SYSTEM TRIGGER TTL TENANT = all_meta;语句为所有 Meta 租户手动触发 TTL 任务。系统租户为指定租户手动触发一次 TTL 任务。
obclient> ALTER SYSTEM TRIGGER TTL TENANT = tenant_name;用户租户为本租户手动触发一次 TTL 任务。
obclient> ALTER SYSTEM TRIGGER TTL;
TTL 任务的状态
TTL 任务执行过程中,可以通过视图 CDB_OB_TTL_TASKS(sys 租户)或 DBA_OB_TTL_TASKS(用户租户)来查看正在执行过程中的 TTL 任务详情,包含表信息、开始时间、修改时间、执行状态等。
系统租户
obclient(root@sys)[(none)]> SELECT * FROM oceanbase.CDB_OB_TTL_TASKS;用户租户
obclient(root@mysqltenant)[(none)]> SELECT * FROM oceanbase.DBA_OB_TTL_TASKS; /*MySQL 模式*/obclient(root@oracletenant)[SYS]> SELECT * FROM SYS.DBA_OB_TTL_TASKS; /*Oracle 模式*/
用户租户下查询结果的示例如下:
+------------+----------+---------+----------------------------+----------------------------+--------------+------------+------------+------------+
| TABLE_NAME | TABLE_ID | TASK_ID | START_TIME | MODIFIED_TIME | TRIGGER_TYPE | STATUS | RET_CODE | TASK_TYPE |
+------------+----------+---------+----------------------------+----------------------------+--------------+------------+------------+------------+
| NULL | -1 | 1 | 2026-01-28 17:31:27.624387 | 2026-01-28 17:31:27.624387 | USER | TRIGGERING | OB_SUCCESS | COMPACTION |
+------------+----------+---------+----------------------------+----------------------------+--------------+------------+------------+------------+
1 row in set
查询结果中,相关字段的详细说明,参见 CDB_OB_TTL_TASKS 和 DBA_OB_TTL_TASKS。
TTL 任务执行结束后,还可以通过视图 CDB_OB_TTL_TASK_HISTORY(sys 租户) 或 DBA_OB_TTL_TASK_HISTORY(用户租户) 来查看已完成的 TTL 任务历史。
注意
TTL 任务历史信息的数据保留时间受租户级配置项 kv_ttl_history_recycle_interval 控制,默认保留 7 天。
TTL 任务的管控
TTL 任务执行过程中,支持手动暂停、恢复或取消 TTL 任务。
暂停 TTL 任务
手动或定时触发 TTL 任务后,可以根据业务需要,手动暂停正在执行的 TTL 任务。
系统租户暂停所有用户租户的 TTL 任务。
obclient(root@sys)[(none)]> ALTER SYSTEM SUSPEND TTL TENANT = all_user;系统租户暂停指定租户的 TTL 任务。
obclient(root@sys)[(none)]> ALTER SYSTEM SUSPEND TTL TENANT = tenant_name;用户租户暂停本租户的 TTL 任务。
obclient> ALTER SYSTEM SUSPEND TTL;
恢复已暂停的 TTL 任务
TTL 任务被暂停后,可以手动恢复已暂停的 TTL 任务。
系统租户恢复所有用户租户的 TTL 任务。
obclient(root@sys)[(none)]> ALTER SYSTEM RESUME TTL TENANT = all_user;系统租户恢复指定租户的 TTL 任务。
obclient(root@sys)[(none)]> ALTER SYSTEM RESUME TTL TENANT = tenant_name;用户租户恢复本租户的 TTL 任务。
obclient> ALTER SYSTEM RESUME TTL;
取消 TTL 任务
TTL 任务执行过程中,用户可以根据业务需要,手动取消正在执行的 TTL 任务。
系统租户取消所有用户租户的 TTL 任务。
obclient(root@sys)[(none)]> ALTER SYSTEM CANCEL TTL TENANT = all_user;系统租户取消指定租户的 TTL 任务。
obclient(root@sys)[(none)]> ALTER SYSTEM CANCEL TTL TENANT = tenant_name;用户租户取消本租户的 TTL 任务。
obclient> ALTER SYSTEM CANCEL TTL;