---
title: "使用 TTL（Time To Live）功能 - OceanBase 数据库 V5.0.1 | OceanBase 文档中心"
description: 使用 TTL（Time To Live）功能 OceanBase 数据库 SQL 模式下的 TTL（Time To Live）功能提供了过期数据的管理能力。通过对表定义 TTL 策略来设置数据的有效期，再由系统执行过期数据（TTL）任务处理已过期的数据。 对于定义了 TTL 策略的表，系统对过期数据的处理主要分为以下…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 5.0.1

# 使用 TTL（Time To Live）功能

更新时间：2026-07-29 10:39:50

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V5.0.1/zh-CN/700.reference/200.system-management/500.manage-data-storage/400.copaction-ttl.md)  

OceanBase 数据库 SQL 模式下的 TTL（Time To Live）功能提供了过期数据的管理能力。通过对表定义 TTL 策略来设置数据的有效期，再由系统执行过期数据（TTL）任务处理已过期的数据。

对于定义了 TTL 策略的表，系统对过期数据的处理主要分为以下两步：

1. 当 TTL 任务被触发时，具有 TTL 属性的表及其索引表、辅助表会通过事务同步一个标记删除的规则信息，满足规则的数据行会被标记为删除，数据被标记删除后就会对用户不可见。
 2. 对于标记删除的数据，在下次执行 Compaction（合并）时，系统会将数据从存储层彻底删除，以便释放存储空间。

本文主要介绍如何通过命令或者设置周期性任务两种方式来发起过期数据（TTL）任务。

## 注意事项

- 对于 TTL 表，当 TTL 列的值为 NULL 时，该行数据永不过期；当新增列作为 TTL 列时，默认值为 NULL 的行的数据不会过期。
 - 在 TTL 任务同步标记删除信息时，会对表加锁，与旁路导入、DDL、Transfer 等操作互斥。
 - 当主表、索引表、辅助表等所有分区数超过 4000 时，可能会发生事务超时，导致标记删除信息的任务一直失败重试，可以通过调大超时时间解决，语句如下。

  ```shell
  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）这段时间内：

     1. 在 T1 时间点：数据行 `rowkey_A` 未达到过期时间，普通 DML 事务 `trans_B` 可以读取到 `rowkey_A` 的数据。
     2. 在 T2 时间点：数据行 `rowkey_A` 达到过期时间，标记删除信息的事务 `trans_A` 将 `rowkey_A` 标记为删除。
     3. 在 T3 时间点：普通 DML 事务 `trans_B` 再次读取 `rowkey_A`，发现已读取不到该数据。
 - 当 TTL 任务未执行时，用户可以查询到表中符合过期规则的数据，若用户对过期数据有严格的可见性要求，需要在查询 SQL 中添加过滤条件。
 - 在主表及其索引上执行 Offline DDL、新建索引的操作后，表数据会被重写，数据的写入时间会被更新，使得数据过期延迟。
 - 执行 TTL 任务后，过期数据会在 Compaction（合并）过程中异步删除，删除过期数据的过程仅在 OceanBase 数据库内部进行，不会同步给下游的其他应用系统。
 - 为了避免因并发写入而导致的数据丢失，对于使用用户定义的时间列作为 TTL 列的表，TTL 任务仅清理在任务开始前已过期数据，不会清理任务开始后过期的数据。

## TTL 表的定义

### 使用限制

使用 TTL 功能进行过期数据的管理时，对 TTL 表有以下限制：

- 不支持外键约束。
 - 不支持触发器。
 - 不支持向量索引、全文索引。
 - 仅支持 TTL 列为单列，不支持 TTL 列为虚拟列、生成列、表达式。
 - 除了支持内部隐藏列 `ora_rowscn`（记录最后一次更新的时间戳），当前版本还支持用户定义的时间列作为 TTL 列。
 - 对于表更新模式为 `partial_update` 的表，仅支持主键列或内部隐藏列 `ora_rowscn` 作为 TTL 列，且不支持表上带索引。
 - 对于 TTL 列为内部隐藏列 `ora_rowscn` 的表，不允许为该表再添加列名为 `ora_rowscn` 的列。
 - 对于索引表，要求索引必须包含 TTL 列（原有列或 Storing 列形式）。如果现有索引不包含 TTL 列，需要先新建包含 Storing 列的索引后，再删除旧索引。
 - 对于有 LOB 列的表：

     - 允许创建表时使用用户列定义 TTL 属性，且表创建成功后，不允许修改 TTL 列为其他用户列。
     - 不允许为没有 TTL 属性的表新增用户列的 TTL 属性。
     - 允许将 TTL 列从用户定义的时间列切换为内部隐藏列 `ora_rowscn`。
     - 允许删除 TTL 属性。
 - DDL 操作限制：

     - 新增 TTL 属性时，要求所有索引表都包含 TTL 列。
     - 变更 TTL 列时，要求所有索引表都包含新的 TTL 列。
     - 删除 TTL 列时，需要先删除 TTL 属性。

### 创建具有 TTL 属性的表

创建 TTL 表的语句如下：

```sql
CREATE TABLE table_name (table_definition_list) MERGE_ENGINE = {append_only | delete_insert | partial_update}
   TTL [=] col_name + INTERVAL interval_num ttl_unit BY COMPACTION;

```

语句中相关参数说明如下：

- `MERGE_ENGINE`：指定表的更新模式。当前版本支持表更新模式 `MERGE_ENGINE` 为 `delete_insert`、`append-only` 或 `partial_update`。
 - `col_name`：指定 TTL 过滤列。支持指定内部隐藏列 `ora_rowscn`（记录最后一次更新的时间戳）或用户定义的时间列。

  当 TTL 列为用户定义的时间列时，支持的列类型如下：

     - MySQL 模式：DATETIME、TIMESTAMP、DATE
     - Oracle 模式：DATE、TIMESTAMP、TIMESTAMP WITH TIME ZONE、TIMESTAMP WITH LOCAL TIME ZONE
 - `interval_num`：指定过期时间的整数数值，取值范围 [0,+∞)。值为 `0` 时，时间单位 `ttl_unit` 可以为取值中的任意值，表示数据一旦提交即过期。
 - `ttl_unit`：指定过期时间的单位。取值支持 `SECOND`、`MINUTE`、`HOUR`、`DAY`、`MONTH` 或 `YEAR`。

示例如下。

- 示例 1：创建一个数据过期时间为 7 天的 TTL 表。其中，TTL 列为内部隐藏列 `ora_rowscn`。

  MySQL 或 Oracle 模式下，执行以下语句创建 TTL 表。

  ```shell
  obclient> CREATE TABLE ttl_tbl1(
      id INT PRIMARY KEY,
      val VARCHAR(100))
      MERGE_ENGINE = append_only TTL ora_rowscn + INTERVAL 7 DAY BY COMPACTION;

  ```
 - 示例 2：创建一个数据过期时间为 7 天的 TTL 表。其中，TTL 列为用户定义的时间列。

     - MySQL 模式

      ```shell
      obclient(root@mysql001)[infotest]> CREATE TABLE ttl_tbl2(
          order_id INT PRIMARY KEY,
          order_time DATETIME NOT NULL,
          payment_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP)
          MERGE_ENGINE = delete_insert TTL order_time + INTERVAL 7 DAY BY COMPACTION;

      ```
     - oracle 模式

      ```shell
      obclient(SYS@oracle001)[SYS]> CREATE TABLE TTL_TBL2(
          ORDER_ID INT PRIMARY KEY,
          ORDER_TIME DATE NOT NULL,
          PAYMENT_TIME DATE NOT NULL DEFAULT sysdate)
          MERGE_ENGINE = delete_insert TTL ORDER_TIME + INTERVAL 7 DAY BY COMPACTION;

      ```

### 修改表的 TTL 属性

表创建成功后，对于非 TTL 表，可以为表新增 TTL 属性；对于 TTL 表，可以修改 TTL 策略、变更 TTL 列或删除 TTL 属性。

**新增 TTL 属性**

为已有表新增 TTL 属性的语法如下：

```sql
ALTER TABLE table_name TTL [=] col_name + INTERVAL interval_num ttl_unit BY COMPACTION;

```

其中，`col_name` 用于指定 TTL 列，可以指定内部隐藏列 `ora_rowscn` 或用户定义的时间列。

    MySQL 模式   Oracle 模式

以 MySQL 模式为例，假设当前存在一个非 TTL 表 `tbl3`。建表语句如下：

```shell
obclient(root@mysql001)[infotest]> CREATE TABLE tbl3(
      order_id INT,
      order_time DATETIME NOT NULL,
      payment_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY(order_id, order_time));

```

可以为表 `tbl3` 新增 TTL 属性，TTL 列为用户定义的时间列，示例语句如下：

```shell
obclient(root@mysql001)[infotest]> ALTER TABLE tbl3 TTL order_time + INTERVAL 7 DAY BY COMPACTION;

```

或者，也可以通过指定内部隐藏列 `ora_rowscn` 作为 TTL 列来为该表添加 TTL 属性。

```shell
obclient(root@mysql001)[infotest]> ALTER TABLE tbl3 TTL ora_rowscn + INTERVAL 7 DAY BY COMPACTION;

```

需要注意的是，本示例中，由于建表时未显式指定表的更新模型，系统默认为 `partial_update` 模式，而对于表更新模式为 `partial_update` 的表，在添加 TTL 属性时，TTL 列必须是主键列或内部隐藏列 `ora_rowscn`。

以 Oracle 模式为例，假设当前存在一个非 TTL 表 `TBL3`。建表语句如下：

```shell
obclient(SYS@oracle001)[SYS]> CREATE TABLE TBL3(
        ORDER_ID INT,
        ORDER_TIME DATE NOT NULL,
        PAYMENT_TIME DATE NOT NULL DEFAULT sysdate,
        PRIMARY KEY(ORDER_ID, ORDER_TIME));

```

可以为表 `TBL3` 新增 TTL 属性，示例语句如下：

```shell
obclient(SYS@oracle001)[SYS]> ALTER TABLE TBL3 TTL ORDER_TIME + INTERVAL 7 DAY BY COMPACTION;

```

```shell
obclient(SYS@oracle001)[SYS]> ALTER TABLE TBL3 TTL ora_rowscn + INTERVAL 7 DAY BY COMPACTION;

```

**修改 TTL 策略**

TTL 表创建成功后，可以根据业务实际情况，修改表的 TTL 策略，示例语句如下：

```shell
obclient> ALTER TABLE ttl_tbl1 SET TTL ora_rowscn + INTERVAL 1 HOUR BY COMPACTION;

```

**变更 TTL 列**

变更 TTL 列的语法如下：

```sql
ALTER TABLE table_name TTL [=] new_ttl_col + INTERVAL interval_num ttl_unit BY COMPACTION;

```

其中，`new_ttl_col` 用于指定新的 TTL 列，与创建 TTL 表时的要求一致。如果是索引表，要求索引必须包含新的 TTL 列。

以 MySQL 模式为例，假设当前存在一个 TTL 表 `ttl_tbl4`。建表语句如下：

```shell
obclient(root@mysql001)[infotest]> CREATE TABLE ttl_tbl4(
        order_id INT,
        order_time DATETIME NOT NULL,
        payment_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY(order_id, order_time, payment_time))
        MERGE_ENGINE = delete_insert TTL order_time + INTERVAL 7 DAY BY COMPACTION;

```

将表 `ttl_tbl4` 的 TTL 列从 `order_time` 变更为 `payment_time`，示例语句如下。

```shell
obclient(root@mysql001)[infotest]> ALTER TABLE ttl_tbl4 TTL payment_time + INTERVAL 7 DAY BY COMPACTION;

```

以 Oracle 模式为例，假设当前存在一个 TTL 表 `TTL_TBL4`，建表语句如下：

```shell
    obclient(SYS@oracle001)[SYS]> CREATE TABLE TTL_TBL4(
        ORDER_ID INT,
        ORDER_TIME DATE NOT NULL,
        PAYMENT_TIME DATE NOT NULL DEFAULT sysdate,
        PRIMARY KEY(ORDER_ID, ORDER_TIME, PAYMENT_TIME))
        MERGE_ENGINE = delete_insert TTL ORDER_TIME + INTERVAL 7 DAY BY COMPACTION;

```

```shell
obclient(SYS@oracle001)[SYS]> ALTER TABLE TTL_TBL4 TTL PAYMENT_TIME + INTERVAL 7 DAY BY COMPACTION;

```

**删除 TTL 属性**

对于 TTL 表，如果不再需要使用 TTL 功能，可以删除表的 TTL 属性，示例语句如下。

```shell
obclient> ALTER TABLE ttl_tbl1 REMOVE TTL;

```

## TTL 任务的触发

对于每一张定义了 TTL 属性的表，在开启 TTL 功能的情况下，系统内部会定期调度 TTL 任务来处理已过期的数据。执行 TTL 任务后，超过有效期的数据将会不可见，但是数据实际并未删除，过期数据会在 Compaction（合并）过程中异步删除（不占用 clog 和写入带宽）。待 Compaction（合并）任务执行后，过期数据占用的存储空间才会真正释放。

### 开启 TTL 功能

发起 TTL 任务要求当前租户已开启 TTL 功能。TTL 功能的开关由租户级配置项 [enable_ttl](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000006618558)（值为 `True`）控制，该配置项在新建租户、恢复租户的场景下其默认值均为 `False`，需要用户手动开启。

1. 管理员用户登录到集群的 `sys` 租户或用户租户。

   连接示例如下，连接数据库时请以实际环境为准。

   ```shell
   obclient -h10.xx.xx.xx -P2883 -uroot@mysqltenant#obdemo -p***** -A

   ```
 2. 执行以下语句，开启 TTL 功能。

      - 系统租户为指定租户开启 TTL 功能。

       ```shell
       obclient(root@sys)[(none)]> ALTER SYSTEM SET enable_ttl = True TENANT = tenant_name;

       ```
      - 用户租户为本租户开启 TTL 功能。

       ```shell
       obclient> ALTER SYSTEM SET enable_ttl = True;

       ```

### 配置定时触发 TTL 任务的时间

开启 TTL 功能后，系统会根据租户下 TTL 表的数据过期情况，定时触发 TTL 任务。定时触发 TTL 任务的时间通过租户级配置项 [ttl_duty_time](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000006618586) 控制，默认触发时间为每天的凌晨 `01:00`。

`ttl_duty_time` 的时刻点与租户的时区相同，建议设置在租户的业务低峰期、租户每日合并发起之前。例如，修改为凌晨 `02:00`。

修改定时触发时间的操作如下:

   ```
 2. 执行以下语句，修改 TTL 任务的定时触发 TTL 任务的时间。

      - 系统租户为指定租户修改定时触发 TTL 任务的时间。

       ```shell
       obclient(root@sys)[(none)]> ALTER SYSTEM SET ttl_duty_time = '02:00' TENANT = tenant_name;

       ```
      - 用户租户为本租户修改定时触发 TTL 任务的时间。

       ```shell
       obclient> ALTER SYSTEM SET ttl_duty_time = '02:00';

       ```

### 手动触发 TTL 任务

开启 TTL 功能后，用户可以手动触发一次 TTL 任务。

   ```shell
   obclient -h10.xx.xx.xx -P2883 -uroot@sys#obdemo -p***** -A

   ```
 2. 执行以下命令，手动触发一次 TTL 任务。

      - 系统租户为所有用户租户手动触发一次 TTL 任务。

       ```shell
       obclient(root@sys)[(none)]> ALTER SYSTEM TRIGGER TTL TENANT = all_user;

       ```

       #### 注意

       不支持系统租户通过 `ALTER SYSTEM TRIGGER TTL TENANT = all_meta;` 语句为所有 Meta 租户手动触发 TTL 任务。
      - 系统租户为指定租户手动触发一次 TTL 任务。

       ```shell
       obclient> ALTER SYSTEM TRIGGER TTL TENANT = tenant_name;

       ```
      - 用户租户为本租户手动触发一次 TTL 任务。

       ```shell
       obclient> ALTER SYSTEM TRIGGER TTL;

       ```

## TTL 任务的状态

TTL 任务执行过程中，可以通过视图 `CDB_OB_TTL_TASKS`（`sys` 租户）或 `DBA_OB_TTL_TASKS`（用户租户）来查看正在执行过程中的 TTL 任务详情，包含表信息、开始时间、修改时间、执行状态等。

- 系统租户

  ```shell
  obclient(root@sys)[(none)]> SELECT * FROM oceanbase.CDB_OB_TTL_TASKS;

  ```
 - 用户租户

  ```shell
  obclient(root@mysqltenant)[(none)]> SELECT * FROM oceanbase.DBA_OB_TTL_TASKS; /*MySQL 模式*/

  ```

  ```shell
  obclient(root@oracletenant)[SYS]> SELECT * FROM SYS.DBA_OB_TTL_TASKS; /*Oracle 模式*/

  ```

用户租户下查询结果的示例如下：

```shell
+------------+----------+---------+----------------------------+----------------------------+--------------+------------+------------+------------+
| 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](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000006617324) 和 [DBA_OB_TTL_TASKS](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000006617901)。

TTL 任务执行结束后，还可以通过视图 [CDB_OB_TTL_TASK_HISTORY（sys 租户）](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000006617189) 或 [DBA_OB_TTL_TASK_HISTORY（用户租户）](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000006617918) 来查看已完成的 TTL 任务历史。

#### 注意

TTL 任务历史信息的数据保留时间受租户级配置项 [kv_ttl_history_recycle_interval](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000006618695) 控制，默认保留 7 天。

## TTL 任务的管控

TTL 任务执行过程中，支持手动暂停、恢复或取消 TTL 任务。

### 暂停 TTL 任务

手动或定时触发 TTL 任务后，可以根据业务需要，手动暂停正在执行的 TTL 任务。

- 系统租户暂停所有用户租户的 TTL 任务。

  ```shell
  obclient(root@sys)[(none)]> ALTER SYSTEM SUSPEND TTL TENANT = all_user;

  ```
 - 系统租户暂停指定租户的 TTL 任务。

  ```shell
  obclient(root@sys)[(none)]> ALTER SYSTEM SUSPEND TTL TENANT = tenant_name;

  ```
 - 用户租户暂停本租户的 TTL 任务。

  ```shell
  obclient> ALTER SYSTEM SUSPEND TTL;

  ```

### 恢复已暂停的 TTL 任务

TTL 任务被暂停后，可以手动恢复已暂停的 TTL 任务。

- 系统租户恢复所有用户租户的 TTL 任务。

  ```shell
  obclient(root@sys)[(none)]> ALTER SYSTEM RESUME TTL TENANT = all_user;

  ```
 - 系统租户恢复指定租户的 TTL 任务。

  ```shell
  obclient(root@sys)[(none)]> ALTER SYSTEM RESUME TTL TENANT = tenant_name;

  ```
 - 用户租户恢复本租户的 TTL 任务。

  ```shell
  obclient> ALTER SYSTEM RESUME TTL;

  ```

### 取消 TTL 任务

TTL 任务执行过程中，用户可以根据业务需要，手动取消正在执行的 TTL 任务。

- 系统租户取消所有用户租户的 TTL 任务。

  ```shell
  obclient(root@sys)[(none)]> ALTER SYSTEM CANCEL TTL TENANT = all_user;

  ```
 - 系统租户取消指定租户的 TTL 任务。

  ```shell
  obclient(root@sys)[(none)]> ALTER SYSTEM CANCEL TTL TENANT = tenant_name;

  ```
 - 用户租户取消本租户的 TTL 任务。

  ```shell
  obclient> ALTER SYSTEM CANCEL TTL;

  ```

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
