首批通过分布式安全可靠测评,为关键业务系统打造
CTAS 建表成功后,部分通过 CTAS 创建的表被误删
更新时间:2026-05-19 09:51
问题现象
在频繁连续的执行 CTAS(create table as select)操作后,过一段时间可能会发现,本来通过 CTAS 建表成功了的表突然被删除了。
示例如下。
18:21:04.963216 create table tbetftbschedulejob as select * from tbschedulejob where 1 = 2;
18:21:05.014858 create table tbetf_sellerfileinfoarea as select * from tbsellerfileinfoarea where 1 = 2;
18:21:49.194989 create table tbetf_tatranscustom as select * from tbtatranscustom where 1 = 2;
18:23:49.194989 select * from tbetftbschedulejob;
ERROR 1146 (42S02): Table 'test.tbetftbschedulejob' doesn't exist
背景信息
CTAS 建表的正常流程
正常的 CTAS 建表流程是分三步走的,以 create table dst as select * from src; 为例说明。
建一个名为
dst的表,这个表与通常create table建出的表的区别在于这个表的 schema 中session_id不等于0。向 dst 中插入数据。通过执行
insert into dst select * from src;把需要的数据插入到 dst 中。通过
alter table的方式将dst的session_id由非 0 置为 0。
清理任务的正常流程
当 CTAS 建表失败时,正常情况下建表的线程会执行一次 DROP TABLE 的操作删除掉 session_id 不等于 0 的表。但是这个 DROP TABLE 的操作可能会失败,此时就依赖一个每隔 60 秒执行一次的清理任务来清理掉内部表里的脏数据。
正常的清理任务的流程如下。
检查清理标记是否为 True,如果为 True 就进入第 2 步开始清理,否则不做清理。
从 schema_service 获取当前所有的表的 Schema。
依次遍历每一个 Schema,如果 Schema 不是一个临时表(临时表的清理也复用了这个任务),并且 session_id 不等于 0(临时表同样复用了 session_id 不等于 0 的机制)。则认为这个表是 CTAS 遗留的脏数据,会执行一次
DROP TABLE来删除这个表。
关键诊断信息
触发条件
频繁连续的执行 CTAS(create table as select)。
问题原因
目前每当执行一次查询建表后,都会把清理标记置为 true。结合上面的背景说明,可以梳理出整个问题的时间线。

从上面的时间线可以看到只要 s7 发生在 s6 和 s10 之间,就会拿到一个 session_id 不等于 0 的 Schema,导致后面的检查误判。进一步把 CTAS 建表成功的表删除。
问题的风险及影响
这个问题本身出现的概率比较低,但是一旦出现就会导致用户本来已经建好的表被误删,如果用户没有开启回收站,就会有数据丢失的风险。
影响租户
影响 OceanBase 数据库中的 Oracle 租户和 MySQL 租户,对于 SYS 租户无影响。
影响的版本
OceanBase 数据库 V2.2.77 GA(oceanbase-2.2.77-20210508211731)及之后版本、V3.1.2 GA(oceanbase-3.1.2-20210618150922)及之后版本、V3.2.3 GA(oceanbase-3.2.3.0-20220418212020)及之后版本。
解决方法
升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库 V2.2.77 BP14(oceanbase-2.2.77-114000072022120410)、V3.1.2 BP11(oceanbase-3.1.2-111000052023010412)、V3.2.3 BP6 Hotfix2(oceanbase-3.2.3.3-106020042022120915)、V3.2.3 BP6 Hotfix3(oceanbase-3.2.3.3-106030012022121311)、V3.2.3 BP6 Hotfix4(oceanbase-3.2.3.3-106040022022122222)、V3.2.3 BP6 Hotfix5(oceanbase-3.2.3.3-106050012023051617)、V3.2.3 BP7(oceanbase-3.2.3.3-107000092023011911)。
如果已经遇到了这个问题,可以尝试从回收站中恢复用户表。
规避方式
如果还没有遇到这个问题并且短期内无法升级到包含修复的版本,建议不使用 CTAS,或保证两个 CTAS 间隔超过 60 秒进行规避。