---
title: "OBKV-Table 过期数据删除 - OceanBase 数据库 V4.2.1 | OceanBase 文档中心"
description: OBKV-Table 过期数据删除 OBKV-Table 实现了过期数据删除（TTL）的能力，本文介绍如何通过命令或周期任务删除过期数据。 注意 过期数据删除（TTL）功能仅限于 OceanBase KV 场景使用，SQL 场景下禁用，否则会导致不可预期的数据误删除问题。 背景信息 OBKV-Table 提供了过期数…
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

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

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库KV 型 - V 4.2.1

# OBKV-Table 过期数据删除

更新时间：2025-06-16 17:51:48

[编辑](https://github.com/oceanbase/oceanbase-kv/edit/V4.2.1/zh-CN/100.obkv-table/700.obkv-table-reference/290.obkv-table-ttl.md)  

OBKV-Table 实现了过期数据删除（TTL）的能力，本文介绍如何通过命令或周期任务删除过期数据。

#### 注意

过期数据删除（TTL）功能仅限于 OceanBase KV 场景使用，SQL 场景下禁用，否则会导致不可预期的数据误删除问题。

## 背景信息

OBKV-Table 提供了过期数据删除的功能，用户可以为关系表定义过期策略。在定义好过期策略之后，用户可以通过命令或者设置周期性任务两种方式触发删除任务，从而减少存储空间占用。同时，OBKV-Table 也会对过期数据进行过滤，以屏蔽过期数据的可见性。

## 使用说明

由于 OceanBase 数据库使用了 LSM-Tree 架构（删除也是一个追加写的操作），即使通过 TTL 任务删除了过期数据，实际存储空间不仅有可能不降低，而且还可能增加，而最终存储空间的释放还是需要依靠 Major Compaction，因此建议配合 major freeze 同时使用，在 TTL 任务删除完成之后执行 major freeze，例如，可以通过设置 `major_freeze_duty_time` 在 `kv_ttl_duty_duration` 之后实现。

TTL 过期删除任务是一个后台低优先级任务，暂无法保证过期数据立即删除的能力，为了不对系统的性能造成较大影响，在任务的执行过程中如果遇到 MemStore 内存 `MEMSTORE_USED` 超过阈值 `FREEZE_TRIGGER`（可以通过视图 `gv$ob_memstore` 查看）的情况，会暂停当前任务的执行直到内存降低到阈值以下。同时，为了不影响系统的恢复流程，对于正常进行物理恢复的租户，TTL 任务同样也会暂停该租户 TTL 任务的执行，直到租户完成恢复。

### TTL 表的定义

- 创建 TTL 关系表 t1，每行数据在 `b + INTERVAL 12 HOUR` 之后会过期。

  ```sql
  CREATE TABLE t1 (
    a INT PRIMARY KEY,
    b TIMESTAMP DEFAULT current_timestamp ON UPDATE current_timestamp)
  TTL (b + INTERVAL 12 HOUR);

  ```
 - 变更表 t1，修改过期时间为 `b + INTERVAL 1 DAY`。

  ```sql
  ALTER TABLE t1 TTL (b + INTERVAL 1 DAY);

  ```
 - 移除表 t1 的 TTL 属性。

  ```sql
  ALTER TABLE t1 REMOVE TTL;

  ```

表的 TTL 属性通过 `COLUMN_NAME + INTERVAL NUM TTL_UNIT`，其中:

- `COLUMN_NAME` 为表中的已定义属性，类型为 TIMESTAMP 或 DATETIME。
 - `+ INTERVAL`: 为固定部分。
 - `NUM`: 表示过期时间的整型
 - `TTL_UNIT`: 可以是 `SECOND`, `MINUTE`, `HOUR`, `DAY`, `MONTH`, `YEAR`。

### TTL 任务的并行度

可以通过租户级配置项 `ttl_thread_score` 设置 TTL 工作线程数量，默认值为 2。

例如，修改 TTL 任务的并行度为 10:

```sql
ALTER SYSTEM SET ttl_thread_score = 10;

```

### 任务触发

触发 TTL 删除任务有两种方式，管控命令触发和周期性任务触发。

任务触发前需要打开租户的 TTL 任务开关。

```sql
ALTER SYSTEM SET enable_kv_ttl= true; -- 默认值为 false

```

- 管控命令触发

  登录到系统租户，并执行如下命令，触发所有租户的 TTL 任务。

  ```sql
  ALTER SYSTEM trigger TTL;

  ```
 - 设置周期任务

  登录到您需要执行 TTL 任务的租户，执行如下命令设置租户每天 TTL 任务的触发时间。

  ```sql
  ALTER SYSTEM SET kv_ttl_duty_duration = '[22:00:00, 24:00:00]'; // 默认值为 ""，表示不触发周期性 TTL 任务

  ```

登录到系统租户，并执行如下系统命令，可以挂起、恢复和取消正在执行的 TTL 任务。

```sql
ALTER SYSTEM SUSPEND TTL; -- 挂起当前正在执行的 TTL 任务
ALTER SYSTEM RESUME TTL; -- 恢复当前挂起的 TTL 任务
ALTER SYSTEM CANCEL TTL; -- 取消正在执行的 TTL 任务

```

TTL 命令只在用户租户或系统租户下执行有效。在用户租户下执行，只能管控本租户的 TTL 任务；在系统租户下执行，可以管控所有用户的 TTL 任务。

下面以 `TRIGGER` 命令为例，其他命令 `SUSPEND`/`RESUME`/`CANCEL` 的作用租户行为一致：

| 租户 | 命令 | 语义 |
| --- | --- | --- |
| 系统租户 | `ALTER SYSTEM SUSPEND TTL` | 所有用户租户 |
| 系统租户 | `ALTER SYSTEM TRIGGER TTL TENANT = all` | 所有用户租户 |
| 系统租户 | `ALTER SYSTEM TRIGGER TTL TENANT = all_user` | 所有用户租户 |
| 系统租户 | `ALTER SYSTEM TRIGGER TTL TENANT = obkv` | obkv 租户 |
| 系统租户 | `ALTER SYSTEM TRIGGER TTL TENANT = obkv1, obkv2` | 用户租户 obkv1, obkv2 |
| 用户租户 | `ALTER SYSTEM TRIGGER TTL` | 本租户 |

### 查看任务状态

通过视图可以查看当前以及历史 TTL 任务的状态和相关信息，与 TTL 任务相关的视图有四张：

| 视图名称 | 视图作用 |
| --- | --- |
| DBA_OB_KV_TTL_TASKS | 查看当前租户正在执行的 TTL 任务 |
| DBA_OB_KV_TTL_TASK_HISTORY | 查看当前租户的历史 TTL 任务 |
| CDB_OB_KV_TTL_TASKS | 系统租户下查看所有租户正在执行的 TTL 任务 |
| CDB_OB_KV_TTL_TASK_HISTORY | 系统租户下查看所有租户的历史 TTL 任务 |

视图 `DBA_OB_KV_TTL_TASKS` 和 `DBA_OB_KV_TTL_TASK_HISTORY` 字段说明：

| 字段 | 说明 |
| --- | --- |
| TABLE_NAME | 表名 |
| TABLE_ID | 表 ID |
| TABLET_ID | Tablet ID |
| TASK_ID | 任务 ID，从 1 开始 |
| START_TIME | 任务开始时间 |
| END_TIME | 任务结束时间 |
| TRIGGER_TYPE | 任务触发类型，包括 PERIODIC 和 USER 两种 |
| STATUS | 任务当前状态，见任务表状态说明 |
| TTL_DEL_CNT | 关系表删除的记录数量 |
| MAX_VERSION_DEL_CNT | Hbase 表基于 MaxVersions 删除的记录数量，关系表模型中此字段为 0 |
| SCAN_CNT | 任务扫描的记录数量 |
| RET_CODE | 任务返回码 |

视图 `CDB_OB_KV_TTL_TASKS` 和 `CDB_OB_KV_TTL_TASK_HISTORY` 字段说明：

#### 说明

相比较 DBA 视图，只多了一个租户 ID。

| 字段 | 说明 |
| --- | --- |
| TENANT_ID | 租户 ID |
| TABLE_NAME | 表名 |
| TABLE_ID | 表 ID |
| TABLET_ID | Tablet ID |
| TASK_ID | 任务 ID，从 1 开始 |
| START_TIME | 任务开始时间 |
| END_TIME | 任务结束时间 |
| TRIGGER_TYPE | 任务触发类型，包括 PERIODIC 和 USER 两种 |
| STATUS | 任务当前状态，见任务表状态说明 |
| TTL_DEL_CNT | 关系表删除的记录数量 |
| MAX_VERSION_DEL_CNT | Hbase 表基于 MaxVersions 删除的记录数量，关系表模型中此字段为 0 |
| SCAN_CNT | 任务扫描的记录数量 |
| RET_CODE | 任务返回码 |

### 过期数据的可见性

如果使用 OBKV-Table 接口对某条记录进行操作，但是该条记录已经过期，这个时候的表现和该条记录不存在保持一致。例如，关系表中存在一条主键为 `k1` 的过期记录，这个时候再插入一条主键为 `k1` 的记录会成功，而不是报主键冲突。

| 操作 | 过期 | 返回码 | affected rows | 其他 |
| --- | --- | --- | --- | --- |
| insert | N | -5024     OB_ERR_PRIMARY_KEY_DUPLICATE | 0 | |
| insert | Y | 0     OB_SUCCESS | 1 | |
| delete | N | 0     OB_SUCCESS | 1 | |
| delete | Y | 0     OB_SUCCESS | 0 | |
| update | N | 0     OB_SUCCESS | 1 | |
| update | Y | 0     OB_SUCCESS | 0 | |
| replace | N | 0     OB_SUCCESS | 2 | |
| replace | Y | 0     OB_SUCCESS | 1 | |
| insert_or_update | N | 0     OB_SUCCESS | 1 | |
| insert_or_update | Y | 0     OB_SUCCESS | 1 | |
| increment | N | 0     OB_SUCCESS | 1 | |
| increment | Y | 0     OB_SUCCESS | 1 | 除了 increment 列其他列会被写成默认值 |
| append | N | 0     OB_SUCCESS | 1 | |
| append | Y | 0     OB_SUCCESS | 1 | 除了 append 列其他列会被写成默认值 |
| query/get | N | 0     OB_SUCCESS | / | 成功读到数据 |
| query/get | Y | 0     OB_SUCCESS | / | 读不到数据 |

#### 说明

SQL 接口暂时不会对过期数据进行屏蔽，在过期数据被删除任务清理之前，过期数据都是可见的。

### 任务状态说明

对于每一个租户的 TTL 任务，在实际执行时，会被拆分成每个 TTL 表的 Tablet 级别任务，正在执行的租户任务和其 Tablet 任务都会被记录在任务表中，通过任务视图可以查看，历史分区任务会被移动到历史表中，通过历史视图可以查看。

#### 注意

租户级任务的 `TABLE_NAME` 为 `NULL`，`TABLET_ID`、`TABLE_ID` 均为 `-1`。

- 在任务视图 `DBA_OB_KV_TTL_TASKS` 和 `CDB_OB_KV_TTL_TASKS` 中，有两类任务：租户级任务和 Tablet 级任务，对应两类不同状态。
 - 在历史任务视图 `DBA_OB_KV_TTL_TASK_HISTORY` 和 `CDB_OB_KV_TTL_TASK_HISTORY` 中，保存历史租户级任务和 Tablet 任务记录。

Tablet 任务状态

| 任务状态 | 说明 |
| --- | --- |
| PREPARED | 准备状态，还未开始删除过期数据 |
| RUNNING | 运行状态，正在删除该分区过期数据 |
| PENDING | 挂起状态，可以通过命令恢复执行 |
| CANCELED | 取消状态，无法恢复执行 |
| FINISHED | 完成状态，待移动到历史表中 |
| INVALID | 非法状态 |

租户任务状态：

| 任务状态 | 说明 |
| --- | --- |
| RS_TRIGGERING | 表示租户 TTL 任务正在执行中 |
| RS_SUSPENDING | 表示租户 TTL 任务已经挂起 |
| RS_CANCELING | 表示租户 TTL 任务已经取消 |
| RS_MOVING | 表示正在移动所有的 TTL 任务记录到历史表 |
| INVALID | 非法状态 |

### 设置历史任务清理周期

为了避免 TTL 历史任务堆积造成不必要的存储空间浪费，可以通过 `kv_ttl_history_recycle_interval` 配置项设置租户的历史 TTL 任务记录的保存时长（默认为 7 天）。

```sql
ALTER SYSTEM SET kv_ttl_history_recycle_interval= '30d'; -- 设置自动清理超过 30 天的历史 TTL 任务记录

```

## 示例：定时删除过期数据

1. 创建一个 TTL 关系表，并定义每条记录在 c + 10s 之后过期。

   ```sql
   CREATE TABLE ttl_table(a VARCHAR(1024) PRIMARY KEY,
     b VARCHAR(1024),
     c TIMESTAMP)
     TTL(c + INTERVAL 10 SECOND) PARTITION BY KEY(a) PARTITIONS 3;

   ```
 2. 插入数据（可以使用 OBKV-Table/SQL，采用 OBKV-Table 接口插入数据，详细操作，请参见 [客户端简介与使用说明](../100.obkv-table/200.use-of-the-tableapi-client/100.introduction-to-the-client-and-instructions-of-use.md.md）。

   ```sql
   INSERT INTO ttl_table VALUES("k1", "hello obkv", now());
   INSERT INTO ttl_table VALUES("k2", "hello obkv", now());
   INSERT INTO ttl_table VALUES("k3", "hello obkv", now());

   ```
 3. 等待 10s 之后，执行命令触发 TTL 任务执行。

   ```sql
   ALTER SYSTEM SET enable_kv_ttl= true; -- 打开 TTL 任务
   ALTER SYSTEM TRIGGER TTL; -- 从 0 点开始，会尝试触发一次 TTL 任务

   ```
 4. 查看任务执行状态。

   ```shell
   obclient> SELECT * FROM OCEANBASE.DBA_OB_KV_TTL_TASKS;

   ```

   返回结果如下：

   ```shell
   +------------+----------+-----------+---------+----------------------------+----------------------------+--------------+---------------+-------------+---------------------+----------+------------+
   | TABLE_NAME | TABLE_ID | TABLET_ID | TASK_ID | START_TIME                 | END_TIME                   | TRIGGER_TYPE | STATUS        | TTL_DEL_CNT | MAX_VERSION_DEL_CNT | SCAN_CNT | RET_CODE   |
   +------------+----------+-----------+---------+----------------------------+----------------------------+--------------+---------------+-------------+---------------------+----------+------------+
   | ttl_table  |   500002 |    200003 |       1 | 2023-09-27 23:31:30.300276 | 2023-09-27 23:31:35.315848 | USER         | FINISHED      |           2 |                   0 |        2 | OB_SUCCESS |
   | ttl_table  |   500002 |    200002 |       1 | 2023-09-27 23:31:30.300276 | 2023-09-27 23:31:35.320258 | USER         | FINISHED      |           1 |                   0 |        1 | OB_SUCCESS |
   | ttl_table  |   500002 |    200001 |       1 | 2023-09-27 23:31:30.300271 | 2023-09-27 23:31:35.321879 | USER         | FINISHED      |           0 |                   0 |        0 | OB_SUCCESS |
   | NULL       |       -1 |        -1 |       1 | 2023-09-27 23:31:28.675583 | 2023-09-27 23:31:28.675583 | USER         | RS_TRIGGERING |           0 |                   0 |        0 | OB_SUCCESS |
   +------------+----------+-----------+---------+----------------------------+----------------------------+--------------+---------------+-------------+---------------------+----------+------------+
   4 rows in set (0.043 sec)

   ```
 5. 任务执行完成会移动到历史表中，可以通过 OCEANBASE.DBA_OB_KV_TTL_TASK_HISTORY 表进行查看。

   ```shell
   obclient> SELECT * FROM OCEANBASE.DBA_OB_KV_TTL_TASK_HISTORY;

   ```

   返回结果如下：

   ```shell
   +------------+----------+-----------+---------+----------------------------+----------------------------+--------------+----------+-------------+---------------------+----------+------------+
   | TABLE_NAME | TABLE_ID | TABLET_ID | TASK_ID | START_TIME                 | END_TIME                   | TRIGGER_TYPE | STATUS   | TTL_DEL_CNT | MAX_VERSION_DEL_CNT | SCAN_CNT | RET_CODE   |
   +------------+----------+-----------+---------+----------------------------+----------------------------+--------------+----------+-------------+---------------------+----------+------------+
   | ttl_table  |   500002 |    200003 |       1 | 2023-09-27 23:31:30.300276 | 2023-09-27 23:31:35.315848 | USER         | FINISHED |           2 |                   0 |        2 | OB_SUCCESS |
   | ttl_table  |   500002 |    200002 |       1 | 2023-09-27 23:31:30.300276 | 2023-09-27 23:31:35.320258 | USER         | FINISHED |           1 |                   0 |        1 | OB_SUCCESS |
   | ttl_table  |   500002 |    200001 |       1 | 2023-09-27 23:31:30.300271 | 2023-09-27 23:31:35.321879 | USER         | FINISHED |           0 |                   0 |        0 | OB_SUCCESS |
   | NULL       |       -1 |        -1 |       1 | 2023-09-27 23:31:28.675583 | 2023-09-27 23:31:42.526853 | USER         | FINISHED |           0 |                   0 |        0 | OB_SUCCESS |
   +------------+----------+-----------+---------+----------------------------+----------------------------+--------------+----------+-------------+---------------------+----------+------------+
   4 rows in set (0.058 sec)

   ```
 6. 任务执行完成之后，可以看到所有过期数据已经被删除。

   ```shell
   obclient> SELECT * FROM ttl_table;
   Empty set (0.060 sec)

   ```

 上一篇 下一篇 ![有帮助](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) 咨询热线
