---
title: "OBKV-HBase 过期数据删除 - OceanBase 数据库 V4.4.2 | OceanBase 文档中心"
description: OBKV-HBase 过期数据删除 OBKV-HBase 实现了 HBase 模型中的列族（Column Family）级别和单元格（Cell）级别的过期数据删除（TTL，Time To Live）的能力，本文介绍如何通过命令或周期任务删除 Column Family 级别或 Cell 级别的过期数据。 注意 过期数…
---
切换语言

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

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

# OBKV-HBase 过期数据删除

更新时间：2026-07-23 19:56:22

[编辑](https://github.com/oceanbase/oceanbase-kv/edit/V4.4.2/zh-CN/200.obkv-hbase/700.obkv-hbase-reference/500.obkv-hbase-ttl.md)  

OBKV-HBase 实现了 HBase 模型中的列族（Column Family）级别和单元格（Cell）级别的过期数据删除（TTL，Time To Live）的能力，本文介绍如何通过命令或周期任务删除 Column Family 级别或 Cell 级别的过期数据。

#### 注意

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

## 分类

目前 OBKV-HBase 支持 Column Family 及 Cell 级别的 TTL。

| TTL 类型 | 描述 | 启用 | 版本支持 |
| --- | --- | --- | --- |
| Column Family 级别 | 设置 Column Family 级别的 TTL，所有写入该 Column Family 的数据在到达指定时间后会过期。 | 通过在建表语句中指定 `KV_ATTRIBUTES` 参数启用功能。 | - 客户端版本：无要求 - OBServer 版本：V4.2.1/V4.3.3/V4.4.0 及以上 - ODP 版本：无要求 |
| Cell 级别 | Cell 级别的 TTL 允许用户为每个单元格设置独立的过期时间。这意味着即使在同一个 Column Family 中，不同的 Cell 可以有不同的存活时间。通过这种方式，用户可以更灵活地管理数据的生命周期，确保只有最相关的数据被保留。 | 通过建表时创建 TTL 列来启用功能，TTL 列的默认值为 `NULL`。 | - 客户端版本：2.X 版本及以上 - OBServer 版本：V4.4.0 及以上 - ODP 版本：无要求 |

#### 注意

可以同时启用 Column Family 级别和 Cell 级别的 TTL，实际的 TTL 值为二者中最小值。

## 使用说明

TTL 功能的基本使用流程如下：

1. 开启 TTL 功能：设置 `enable_kv_ttl = true` 开启租户的 TTL 任务开关。
 2. 定义 TTL 表：创建表时指定 TTL 属性（Column Family 级别或 Cell 级别）。支持修改/移除 TTL 属性。
 3. 触发删除任务：通过手动命令或设置周期任务触发过期数据删除。支持暂停/恢复/取消正在执行的任务。
 4. 查看任务状态：通过系统视图监控任务执行情况。

#### 注意

Column Family 级别和 Cell 级别的 TTL 除了定义表语法有区别外，其他功能用法一致。

下面详细展开介绍。

### 第一步：开启 TTL 功能

开启 TTL 功能需要设置租户级配置项 `enable_kv_ttl` 为 `true`。

```sql
ALTER SYSTEM SET enable_kv_ttl= true; -- 租户级配置项，默认值为 false

```

### 第二步：定义 TTL 表

这里介绍 Column Family 级别和 Cell 级别的 TTL 定义表语法及示例。

    Column Family 级别   Cell 级别

Column Family 级别的 TTL 功能通过 `KV_ATTRIBUTES` 属性的 `TimeToLive` 和 `MaxVersions` 参数来设置。例如，创建一张 OBKV-HBase 表 `t1$cf1`，指定每行数据的过期时间为 3600 秒，每行数据的最大版本数量为 3。

```sql
CREATE TABLE t1$cf1 (
  K VARBINARY(1024),
  Q VARBINARY(256),
  T BIGINT,
  V VARBINARY(1048576) NOT NULL,
  PRIMARY KEY(K, Q, T))
-- TimeToLive 单位为秒
KV_ATTRIBUTES ='{"Hbase": {"TimeToLive": 3600, "MaxVersions": 3}}'
PARTITION BY KEY(K) PARTITIONS 97;

```

修改 OBKV-HBase 表 `t1$cf1`，移除 `TimeToLive` 属性，修改最大版本数量为 4。

```sql
ALTER TABLE t1$cf1 KV_ATTRIBUTES ='{"Hbase": {"MaxVersions": 4}}';

```

移除 OBKV-HBase 表 `t1$cf1` 的过期属性。

```sql
ALTER TABLE t1$cf1 KV_ATTRIBUTES ='{"Hbase": {}}';

```

Cell 级别的 TTL 功能通过在表中创建一个 TTL 列来设置。例如，创建一张 OBKV-HBase 表 `t1$cf1`，包含 TTL 列。

```sql
CREATE TABLE `t1$cf1` (
  `K` VARBINARY(1024) NOT NULL,
  `Q` VARBINARY(256) NOT NULL,
  `T` BIGINT(20) NOT NULL,
  `V` VARBINARY(1024) DEFAULT NULL,
  -- 创建 Cell 级别 TTL，具体参数在执行 put/increment/append/get/scan/delete DML 操作时指定，单位为毫秒
  -- TTL 列必须创建在第 5 列的位置
  `TTL` BIGINT(20) DEFAULT NULL,
  PRIMARY KEY (`K`, `Q`, `T`)
);

```

### 第三步：任务触发

触发 TTL 删除任务有两种方式：

- 管控命令触发：需登录到系统租户，用于触发所有租户的 TTL 任务。除了触发任务，系统租户还支持暂停、恢复和取消正在执行的 TTL 任务。
 - 周期性任务触发：需登陆到您需要执行 TTL 任务的用户租户，设置该用户租户每天的 TTL 任务触发时间。

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

    管控命令触发示例   周期性任务触发示例

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

```sql
ALTER SYSTEM TRIGGER TTL;

```

暂停正在执行的 TTL 任务，命令如下：

```sql
ALTER SYSTEM SUSPEND TTL;

```

恢复暂停的 TTL 任务，命令如下：

```sql
ALTER SYSTEM RESUME TTL;

```

取消正在执行的 TTL 任务，命令如下：

```sql
ALTER SYSTEM CANCEL TTL;

```

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

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

```

### 第四步：查看任务状态

通过视图可以查看当前以及历史 TTL 任务的状态和相关信息，与 TTL 任务相关的视图有四张。具体请参见[OBKV-HBase 相关视图](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005280335)。

#### 任务类型

当前 OBKV-HBase 的 TTL 任务有两种类型：Normal TTL 任务和 Hbase Rowkey TTL 任务，对应任务状态表中的 `task_type` 列。

- Normal TTL 任务

通过命令或者周期性任务触发，首先生成一个租户级的 TTL 任务（对应 `table id` 为 `-1` 的那条记录），同时对所有的定义了过期规则的表，生成 tablet 级 TTL 任务并执行，每个 tablet 任务会对该 tablet 进行全扫描来找出并删除过期数据，当所有的 tablet 任务执行完成之后，会将这次租户 TTL 任务的所有任务记录移动到历史表中。

- HBase Rowkey TTL 任务

固定周期性的触发，每天会将旧的 HBase rowkey TTL 任务记录移动到历史表中，生成一个新的租户级别的 HBase rowkey TTL 任务（对应 `table id` 为 `-2`），并对所有的定义了过期规则的表生成 tablet 级 TTL 任务，该 tablet 任务执行需要基于用户请求触发，会收集 Scan/Get 操作中涉及到的过期 row（即 TTL 或 MaxVersion 过期的 row），并生成只扫描该 row 的 TTL 任务，任务执行后会将执结果（scan_cnt/max_version_del_cnt/ttl_del_cnt）汇总到对应的 tablet 任务上。

#### 任务状态说明

TTL 任务分为租户级任务和 Tablet 级任务两类，对应不同的状态，均可在任务视图 `DBA_OB_KV_TTL_TASKS` 和 `CDB_OB_KV_TTL_TASKS` 以及历史任务视图 `DBA_OB_KV_TTL_TASK_HISTORY` 和 `CDB_OB_KV_TTL_TASK_HISTORY` 中查看。

#### 注意

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

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 天）。

例如，设置自动清理超过 30 天的历史 TTL 任务记录，命令如下：

```sql
ALTER SYSTEM SET kv_ttl_history_recycle_interval= '30d';

```

## 性能优化

### 设置并行度

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

例如，修改 TTL 任务的工作线程数量为 10：

```sql
ALTER SYSTEM SET ttl_thread_score = 10;

```

## 注意事项

### 过滤变更日志

#### 注意

该功能从 V4.4.2 BP1 版本开始支持，需要搭配 V4.4.2 BP1 及以上版本的 liboblog 使用。

TTL 任务在删除过期数据时会产生大量变更日志（Change Log，CLOG）。默认情况下，CDC（liboblog）会正常捕获并消费这些变更日志，再同步给下游组件。在过期数据量较大的场景下，TTL 删除过期数据产生的大量日志会给 CDC 链路带来额外的处理压力及资源开销。

为减轻 CDC 链路资源压力，可开启 CDC 侧 TTL 变更日志过滤能力（`filter_ttl_delete_log`）。开启后，TTL 任务产生的变更日志会被 CDC 过滤，不再向下游输出。默认不启用过滤，即 TTL 变更日志会被 CDC 正常消费；开启过滤后，仅影响 TTL 任务变更日志，不改变 TTL 任务本身的执行逻辑。

### 过期数据的可见性

如果使用 OBKV-HBase 接口对某条记录进行操作，但是该条记录已经过期，这个时候的表现和该条记录不存在保持一致。例如，关系表中存在一条主键为 `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 过期删除任务是一个后台低优先级任务，暂无法保证过期数据立即删除。为了不对系统性能造成较大影响，在以下情况下任务会自动暂停：

- 内存压力：当 MemStore 内存 `MEMSTORE_USED` 超过阈值 `FREEZE_TRIGGER` 时，任务会暂停执行，直到内存降低到阈值以下。可通过视图 [GV$OB_MEMSTORE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015125) 查看内存使用情况。
 - 物理恢复期间：对于正在进行物理恢复的租户，TTL 任务会暂停执行，直到租户完成恢复。

### 存储空间释放

由于 OceanBase 数据库采用 LSM-Tree 架构，删除操作本质上是一次追加写入（写入删除标记）。因此，TTL 任务删除过期数据后，实际存储空间不会立即释放，甚至可能暂时增加。存储空间的最终释放依赖于 Major Compaction 过程。

为了确保存储空间能够及时释放，建议将 TTL 任务与 Major Freeze 配合使用：

1. 设置 TTL 任务的执行时间窗口（[kv_ttl_duty_duration](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015588)）。
 2. 将 Major Freeze 的执行时间（[major_freeze_duty_time](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002015510)）设置在 TTL 任务窗口之后。

这样可以在 TTL 任务完成后自动触发 Major Compaction，从而释放存储空间。

## 完整示例

### Column Family 级别

1. 启用 TTL 功能。

   ```sql
   ALTER SYSTEM SET enable_kv_ttl= true;

   ```
 2. 创建一个 OBKV-HBase 表。

   ```sql
   CREATE TABLE t1$cf1 (
     K VARBINARY(1024),
     Q VARBINARY(256),
     T BIGINT,
     V VARBINARY(1048576) NOT NULL,
     PRIMARY KEY(K, Q, T))
   KV_ATTRIBUTES ='{"Hbase": {"TimeToLive": 3600, "MaxVersions": 3}}'
   PARTITION BY KEY(K) PARTITIONS 3;

   ```
 3. 模拟 OBKV-HBase 插入数据。

   实际插入数据过程请参考 [OBKV-HBase 客户端使用介绍](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005280328)，示例如下：

   ```sql
   INSERT INTO t1$cf1 VALUES
   ("row1", "cq1", -truncate(time_to_usec(date_sub(now(), interval +1 hour))/1000, 0), "del"),
   ("row1", "cq1", -truncate(time_to_usec(now())/1000, 0), "no del"),
   ("row2", "cq1", -truncate(time_to_usec(date_sub(now(), interval +1 hour))/1000, 0), "del"),
   ("row2", "cq1", -truncate(time_to_usec(now())/1000, 0), "no del"),
   ("row3", "cq1", -truncate(time_to_usec(date_sub(now(), interval +1 hour))/1000, 0), "del"),
   ("row3", "cq1", -truncate(time_to_usec(now())/1000, 0), "no del"),
   ("row4", "cq1", -truncate(time_to_usec(date_sub(now(), interval +1 hour))/1000, 0), "del"),
   ("row4", "cq1", -truncate(time_to_usec(now())/1000, 0), "no del");

   ```
 4. 设置租户每日 TTL 任务时间，自动触发任务。

   ```sql
   -- 从 0 点开始，会尝试触发一次 TTL 任务
   ALTER SYSTEM SET kv_ttl_duty_duration = '[00:00:00, 23:59:59]';

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

      - 查看当前任务（执行结果取决于实际任务执行状态）。

       ```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   |
       +------------+----------+-----------+---------+----------------------------+----------------------------+--------------+---------------+-------------+---------------------+----------+------------+
       | NULL       |       -1 |        -1 |       1 | 2023-09-28 11:35:02.695292 | 2023-09-28 11:35:17.720627 | PERIODIC     | RS_TRIGGERING |           0 |                   0 |        0 | OB_SUCCESS |
       | t1$cf1     |   500002 |    200001 |       1 | 2023-09-28 11:35:06.612708 | 2023-09-28 11:35:06.612708 | PERIODIC     | PREPARED      |           0 |                   0 |        0 | OB_SUCCESS |
       | t1$cf1     |   500002 |    200002 |       1 | 2023-09-28 11:35:06.612711 | 2023-09-28 11:35:06.612711 | PERIODIC     | PREPARED      |           0 |                   0 |        0 | OB_SUCCESS |
       | t1$cf1     |   500002 |    200003 |       1 | 2023-09-28 11:35:06.612712 | 2023-09-28 11:35:06.612712 | PERIODIC     | PREPARED      |           0 |                   0 |        0 | OB_SUCCESS |
       +------------+----------+-----------+---------+----------------------------+----------------------------+--------------+---------------+-------------+---------------------+----------+------------+
       4 rows in set

       ```
      - 查看历史任务（执行结果取决实际任务执行状态）。

       ```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   |
       +------------+----------+-----------+---------+----------------------------+----------------------------+--------------+----------+-------------+---------------------+----------+------------+
       | NULL       |       -1 |        -1 |       1 | 2023-09-28 11:35:02.695292 | 2023-09-28 11:35:17.720627 | PERIODIC     | FINISHED |           0 |                   0 |        0 | OB_SUCCESS |
       | t1$cf1     |   500002 |    200001 |       1 | 2023-09-28 11:35:06.612708 | 2023-09-28 11:35:11.634029 | PERIODIC     | FINISHED |           1 |                   0 |        2 | OB_SUCCESS |
       | t1$cf1     |   500002 |    200002 |       1 | 2023-09-28 11:35:06.612711 | 2023-09-28 11:35:11.632463 | PERIODIC     | FINISHED |           1 |                   0 |        2 | OB_SUCCESS |
       | t1$cf1     |   500002 |    200003 |       1 | 2023-09-28 11:35:06.612712 | 2023-09-28 11:35:11.627921 | PERIODIC     | FINISHED |           2 |                   0 |        4 | OB_SUCCESS |
       +------------+----------+-----------+---------+----------------------------+----------------------------+--------------+----------+-------------+---------------------+----------+------------+
       4 rows in set

       ```
 6. 查看当前 OBKV-HBase 表中的数据。

   ```shell
   obclient> SELECT * FROM t1$cf1;

   ```

   返回结果如下：

   ```shell
   +------+-----+----------------+--------+
   | K    | Q   | T              | V      |
   +------+-----+----------------+--------+
   | row3 | cq1 | -1695872081000 | no del |
   | row4 | cq1 | -1695872081000 | no del |
   | row1 | cq1 | -1695872081000 | no del |
   | row2 | cq1 | -1695872081000 | no del |
   +------+-----+----------------+--------+
   4 rows in set

   ```

### Cell 级别

创建一张 OBKV-HBase 表 `t1$cf1`，包含 TTL 列。

```

数据操作示例如下：

- put 操作

  ```shell
  Put put1 = new Put(key1.getBytes());
  put1.addColumn(family.getBytes(), column1.getBytes(), toBytes(11L));
  put1.addColumn(family.getBytes(), column2.getBytes(), toBytes(11L));
  # 该 put 操作中每个 Cell 的 TTL 被设置为 300 毫秒，意味着它们在 300 毫秒后会被视为过期。
  # 过期数据的删除要依赖 TTL 后台任务的执行。如果没有开启 Rowkey TTL 任务，在过期数据被转储之前，你仍然可以通过 SQL 查询到这些过期的 Cell；如果开启了 Rowkey TTL 任务，那么在下一次扫描前，可以通过 SQL 查询到这些 Cell 的数据，但不能通过 get 操作获取，因为 get 操作会自动过滤掉过期的 Cell。
  put1.setTTL(300);
  hTable.put(put1);

  ```
 - increment 操作

  ```shell
  Increment increment = new Increment(key1.getBytes());
  increment.addColumn(family.getBytes(), column1.getBytes(), 1L);
  increment.addColumn(family.getBytes(), column2.getBytes(), 2L);
  # 如果 increment 没有设置 TTL，则 increment 出来的新 Cell 使用的 TTL 值就是查询出的 Cell 的值
  # 如果 increment 设置了 TTL，那么 increment 出来的新 Cell 的 TTL 值就是 increment 设置的值
  # 该 increment 操作结束后，在 500 毫秒以内查询，预期能查询到新插入的 Cell；500 毫秒后查询该表，则预期查询不到。
  increment.setTTL(500);
  hTable.increment(increment);

  ```
 - append 操作

  ```shell
  Append append = new Append(key1.getBytes());
  append.add(family.getBytes(), column1.getBytes(), toBytes(11L));
  append.add(family.getBytes(), column2.getBytes(), toBytes(11L));
  # 同 increment 操作
  append.setTTL(500);
  hTable.append(append);

  ```
 - get/scan 操作

  get/scan 操作不支持设置 TTL，但在查询时会自动过滤过期的 Cell。同时，扫描的 Cell 会记录其 Rowkey 的过期状态。如果 Rowkey 中有 Cell 过期，将触发 Rowkey TTL，及时清理过期的 Cell。
 - delete 操作

  delete 操作有 `setTTL` 接口，设置了 TTL 的 delete 操作会报错。它会删除未过期的最新版本。如果最新版本已过期，则会删除第二个版本的 Cell。例如，当最新版本的 Cell 设置了 TTL 并过期后，执行 delete 操作将删除下一个版本的 Cell。部分示例代码如下：

  ```shell
  hTable.put(put1);
  hTable.put(put2);
  Delete del = new Delete(key1.getBytes());
  del.addColumn(family.getBytes(), column1.getBytes());
  hTable.delete(del);

  ```

  执行 delete 操作前表数据如下：

  ```sql
  +------+-----+----------------+--------+--------+
  | K    | Q   | T              | V      | TTL    |
  +------+-----+----------------+--------+--------+
  | key1 | cf1 | -1741157319257 | value | 5       |
  | key1 | cf1 | -1741157319182 | value | NULL    |
  +------+-----+----------------+--------+--------+
  2 rows in set

  ```

  执行 delete 操作后表数据如下：

  ```sql
  +------+-----+----------------+--------+--------+
  | K    | Q   | T              | V      | TTL    |
  +------+-----+----------------+--------+--------+
  | key1 | cf1 | -1741157319257 | value | 5    |
  +------+-----+----------------+--------+--------+
  1 row in set

  ```

  这里可以看到，删除了第二个版本的数据，没删除过期的数据。

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