首批通过分布式安全可靠测评,为关键业务系统打造
OceanBase 数据库执行计划生成模块使用内存过多
更新时间:2026-05-15 09:06
问题现象
查询的计划生成时间很长,并且使用内存很多。
关键诊断信息
触发条件
SQL 有 union all,每一支的查询都比较类似,并且每一支都包含不同的索引条件,这些索引条件比较复杂。
事前巡检
SQL 有 union all,每一支的查询都比较类似,并且每一支都包含不同的索引条件,这些索引条件比较复杂,例如:
select * from t1 where i1 in (1,2,3,4,5,6,) unoin all select * from t1 where i1 in (4,5,6,7,8,9);
事后诊断
监控显示租户内存使用过多,通过 __all_virtual_mem_leak_checker_info 内部字典查看内存使用最多的堆栈信息,通过解析堆栈信息,可以找到 query range 相关的堆栈,例如:preliminary_extract_query_range。
问题原因
CTE 优化生成了复杂的索引条件,而 query range 抽取复杂条件费时费内存。
问题的风险及影响
可能导致查询无法生成计划,同时可能打爆租户内存。
影响租户
影响 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)及之后版本、V3.2.4 GA(oceanbase-3.2.4.0-100000072022102819)及之后版本、V4.1.0 GA(oceanbase-4.1.0.0-100001122023040322)及之后版本。
解决方法
升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库企业版 V3.2.3 BP11(oceanbase-3.2.3.3-111000032024070822)、V3.2.4 BP6(oceanbase-3.2.4.6-106000062023110109)、V4.1.2 BP3(oceanbase-4.1.0.2-103000072023081111)。
通过关闭 CTE 优化绕过问题。
OceanBase 数据库 V3.2.3 BP8 和 V3.2.4 BP3 可以通过租户隐藏配置项
_xsolapi_generate_with_clause关闭 CTE 优化绕过该问题,具体方法如下。obclient> alter system set "_xsolapi_generate_with_clause"=false;
规避方式
为了解决 query range 抽取内存消耗过高的问题,引入了一个配置项 range_optimizer_max_mem_size 用于控制 query range 抽取时使用的内存上限,当抽取时使用的内存超过配置的上限后则不抽取 range。 这个配置项的默认大小是 128M,并且可配置的上限为 1G(考虑到这个配置项可能导致业务升级后本来能抽取 range 的 SQL 因为抽不出 range 导致性能下降,因此将这个配置项的默认值和可配置范围做出调整。该配置项从 V4.3.0 版本开始取值范围由 [16M,1G] 调整为 [0M,+∞),详情参见:range_optimizer_max_mem_size。