问题现象
在 OceanBase 数据库集群执行执行 SQL 报错 ORA-00600: internal error code, arguments: -4016, Internal error 无法查看执行计划,在计划生产阶段就报错,无法通过加 /*+ NO_REWRITE */ Hint 方式规避。
关键诊断信息
报错的 SQL 是关联子查询并且子查询的基表是二级分区的分区表,有两个分区键,一个分区键在子查询中为常量
(tmp.month_id = 202405),一个为关联子查询的关联列(and tmp.client_id = t3.client_id)图片字体绿色区域为关联子查询,红色区域字体过滤条件为分区键。
执行报错
ORA-00600: internal error code, arguments: -4016, Internal error。
查询报错 SQL 的 trace 日志
grep 'can not find part expr'在get_repartition_keys有 4016 的报错。
使用
/*+USE_DAS(TABLE_NAME)*/Hint 规避后执行成功,可以判断命中此问题。
问题原因
报错 SQL 是一个关联子查询,子查询查询表为一个二级分区有两列分区键 (month_id) 和 (client_id),其中一个分区键在子查询中为常量 (tmp.month_id = 202405),一个为关联子查询的关联列 (and tmp.client_id = t3.client_id), 改 SQL 生成 sunplan filter 的 partition key 计划时,无法转换为来自子查询上层表的列,代码逻辑没有做相应处理,触发报错。

CREATE TABLE "T_1" (
"MONTH_ID" NUMBER(10),
"CLIENT_ID" VARCHAR2(18),
"VALID_CLIENT" VARCHAR2(1)
) COMPRESS FOR ARCHIVE REPLICA_NUM = 3 BLOCK_SIZE = 16384
partition by hash("CLIENT_ID") subpartition by range("MONTH_ID") subpartition template (
subpartition "P202406" values less than (202407),
subpartition "P202407" values less than (202408))
(partition "P01",
partition "P02",
partition "P03")
SELECT
t3.CLIENT_ID AS "clientId",
(
SELECT
tmp.valid_client
FROM
T_1 tmp
WHERE
tmp.month_id = 202405
and tmp.client_id = t3.client_id
) AS "validClientKey"
from T_1 t3;
问题的风险及影响
SQL 执行报错或者 EXPLAIN SQL 报错。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
适用版本
OceanBase 数据库 V4.x 版本。
解决方法
升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库 V4.2.3(oceanbase-4.2.3.0-100000052024041220)版本、V4.3.0(oceanbase-4.3.0.0-100010022024022718)版本。
规避方式
子查询里加 /*+USE_DAS(TABLE_NAME)*/ Hint 规避。