---
title: OceanBase 数据库中 TRUNCATE 语句注意事项 -OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于OceanBase 数据库中 TRUNCATE 语句注意事项 相关的常见问题和使用技巧，帮助您快速解决OceanBase 数据库中 TRUNCATE 语句注意事项 的难题。
---
切换语言

- 简体中文
- English

划线反馈

# OceanBase 数据库中 TRUNCATE 语句注意事项

更新时间：2023-11-14 03:16

适用版本： V2.1.x、V2.2.x、V3.1.x、V3.2.x 内容类型：TechNote  

OceanBase 数据库中的 TRUNCATE 语句会先 DROP 该表所有分区，再为其重新创建新的分区。这个过程物理数据不做改动，但会变更表 ID。后续原表 ID 的实体会执行 GC（Garbage Collection，回收处理机制） 流程，留下新 `table_id` 的实体继续提供读写服务。

OceanBase 数据库在执行 TRUNCATE 时不会对表加锁，因此会出现一个事务执行过程中，新旧表 ID 对应的数据实体分别写了该事务的一部分数据，后续原表 ID 的实体执行了 GC，用户查询该事务的修改时，只查询到一部分数据，从而出现正确性问题。

有关 OceanBase 的回收处理机制，请参见 [OceanBase 数据库的 GC 回收处理机制](https://www.oceanbase.com/knowledge-base/oceanbase-database-20000000147)。

## 问题复现

在 OceanBase 数据库中开启两个会话 S1 和 S2。

1. 在 S1 中执行以下 SQL 语句，向 fruit 表中插入数据。

   ```unknow
   obclient> BEGIN;
   obclient> INSERT INTO fruit VALUES (1,1);

   ```
 2. 在 S2 中对 fruit 表执行 TRUNCATE。

   ```unknow
   obclient> TRUNCATE TABLE fruit;

   ```
 3. 在 S1 中执行以下 SQL 语句，向 fruit 表中插入第二行数据，并提交事务。

   ```unknow
   obclient> INSERT INTO fruit VALUES (2,2);
   obclient> COMMIT;

   ```
 4. 在 S2 中查询 fruit 表上的事务。

   ```unknow
   obclient> SELECT * FROM fruit;
   +------+------+
   | c1   | c2   |
   +------+------+
   |    2 |    2 |
   +------+------+
   1 row in set (0.01 sec)

   obclient> SHOW RECYCLEBIN;
   +---------------------------------------+---------------+-------+----------------------------+
   | OBJECT_NAME                           | ORIGINAL_NAME | TYPE  | CREATETIME                 |
   +---------------------------------------+---------------+-------+----------------------------+
   | __recycle_$_48200632_1607431261749248 | fruit         | TABLE | 2020-12-18 19:31:16.723301 |
   +---------------------------------------+---------------+-------+----------------------------+

   ```
 5. 在 S2 中闪回 fruit 表上的修改，将闪回后的表重命名为 fruit_2。

   ```unknow
   obclient> FLASHBACK TABLE fruit TO BEFORE DROP RENAME TO fruit_2;

   obclient> SELECT * FROM fruit_2;
   +------+------+
   | c1   | c2   |
   +------+------+
   |    1 |    1 |
   +------+------+
   1 row in set (0.01 sec)

   ```

由此可见，S1 中一个事务前后的数据分别插入了不同的表。这是由于执行 TRUNCATE TABLE 语句过程中，如果并发执行事务，由于 DDL 语句与 DML 语句不互相锁，会导致事务有一半会在前一个对象上。

#### 说明

虽然 OceanBase 数据库在并发事务中 DDL 语句与 DML 语句不会互相锁定，但同一个会话中的多条语句仍满足因果序。

## 运维建议

可以通过以下两种方式之一规避该问题。

- 在执行 `TRUNCATE TABLE` 语句的过程中，为了避免遇到上述问题，需要确保 `TRUNCATE` 之前已经没有事务存在。

  可以使用以下 SQL 查询是否存在事务，其中 `table_id` 为待执行 `TRUNCATE` 语句的表 ID。如果查询结果为空集，则表示没有已存在的事务。

  ```unknow
  obclient> SELECT count(1) FROM __all_virtual_trans_stat WHERE 'partition' LIKE '%table_id%';

  ```
 - 关闭 `ob_enable_truncate_flashback` 变量。

  `ob_enable_truncate_flashback` 变量用于控制是否启用表截断的闪回，避免在执行 TRUNCATE TABLE 的表上进行闪回操作 。有关该系统变量的详细信息，请参见《OceanBase 数据库 参考指南》中的 **系统变量** 章节。

  ```unknow
  obclient> SET GLOBAL ob_enable_truncate_flashback=0;

  ```

Previous

[重整数据 DDL 的执行速度优化](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000217849)

Next

[介绍宕机对于 DDL 的影响](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000564142) ![有帮助](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) 咨询热线
