基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
大量 union all 与 not in 条件 SQL 语句执行报错 4013
更新时间:2026-08-25 08:16
问题现象
客户生产环境执行固定 SQL 报错 4013。排查发现,该 SQL 执行期间 SqlExecContext 内存异常上涨,最终触发报错。报错 SQL 较长,包含 13 个 union all,且每个 select 中都有较多 in 条件;减少 union all 数量可以规避。 | OBServer 版本 | 执行现象 | | --- | --- | | 3.2.3.3-111010012024081311 | 执行正常 14s | | 3.2.3.3-107030052023031712 | 执行报错 4013 |
关键诊断信息
触发条件
SQL 中包含大量 union all 语句(13 个以上)以及大量的 not in 条件。
事前巡检
检查 SQL 是否存在 union/union all 语句 + 大量 not in 条件的问题写法,问题 SQL 结构示例如下:
with now_contr as (
select
....
from
....
where
cl..... in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
and ....
),
last_contr as (
select
....
from
....
where
cl.pk_org in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
and ....
),
now_inner_move as (
select
....
from
....
where
.... in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
and im..... not in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
),
out_person as (
select
....
from
....
where
.... in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
union
select
....
from
....
where
.... in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
union
select
....
from
....
where
.... in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
union
select
....
from
....
where
.... in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
union
select
....
from
....
where
.... in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
and .... not in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
union
select
....
from
....
where
.... in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
and .... not in (
'000U',
'000W',
'000X',
'000Y',
'000Z',
'0010',
'0011',
'0012',
'0013',
'0821'
)
)
....
事后诊断
在 observer.log 中检索关键词 failed to extract query range:
grep 'failed to extract query range' observer.log
若返回结果中包含 ret=-4013,且 SQL 为大量 union/union all 语句 + 大量 not in 条件的形式,则命中此问题。 日志关键记录示例如下(已省略线程号、TraceID 等内部标识):
[2025-03-19 12:44:17.727301] WARN alloc ... [OOPS] alloc failed reason: tenant memory has reached the upper limit(tenant_id: 1004, tenant_hold: 68719476736, tenant_limit: 68719476736, alloc_size: 2097152)
[2025-03-19 12:44:17.727309] WARN alloc ... oops, alloc failed, tenant_id=1004, ctx_id=5, ctx_name=SQL_EXEC_CTX_ID, ctx_hold=61027123200, tenant_hold=68719476736, tenant_limit=68719476736
[2025-03-19 12:44:17.727357] ERROR [SQL.REWRITE] ... alloc ObKeyPart failed(ret=-4013)
[2025-03-19 12:44:38.219854] WARN [SQL.JO] ... failed to extract query range(ret=-4013, index_id=1103909674353920)
问题原因
该问题由 CTE 优化引入:CTE 优化会为复杂查询生成复杂的索引条件,生成和提取这些条件需要消耗大量内存;在未启用 IN 条件优化的 OBServer 版本上,SQL 执行期间内存持续膨胀,最终触发 4013(No memory or reach tenant memory limit)报错。
问题的风险及影响
执行含大量 union all 和 not in 条件的 SQL 时报错 4013(No memory or reach tenant memory limit),导致 SQL 执行失败,影响业务查询正常运行。
影响租户
| sys | MySQL | Oracle |
|---|---|---|
| YES | YES | YES |
影响版本
| 影响版本 | 开始版本 | 修复的 BP 版本 | (区间内)修复的 Hotfix 版本 |
|---|---|---|---|
| 3.2.3.3(BP7、BP8) | 3.2.3.3-107030052023031712 | 3.2.3.3-111010012024081311 |
解决方法
- OBServer 3.2.3 BP0~BP7:该版本区间没有
_xsolapi_generate_with_clause配置项,可在相关 SQL 的 select 后添加/*+inline*/Hint,控制 CTE 抽取及展开,避免 CTE 抽取导致的内存膨胀。 - OBServer 3.2.3 BP8~BP10:关闭 CTE 抽取优化,避免抽取复杂索引条件的 query range 消耗大量内存。执行以下命令:
alter system set "_xsolapi_generate_with_clause" = 0;
规避方式
- OBServer 3.2.3 BP0~BP7:可在相关 SQL 的 select 后添加
/*+inline*/Hint,控制 CTE 抽取及展开,避免 CTE 抽取导致的内存膨胀。 - OBServer 3.2.3 BP8~BP10:执行
alter system set "_xsolapi_generate_with_clause" = 0;关闭 CTE 抽取优化。