首批通过分布式安全可靠测评,为关键业务系统打造
全局索引回表可能引起 TableLookup 内存剧烈膨胀的原因和解决方法
更新时间:2026-05-22 08:56
问题现象
全局索引扫描的结果集很大或者回表涉及到的分区数较多时,可能触发该问题,该问题的表现是当 SQL 执行过程中,SqlTableLookup 模块内存一直增长,但 SQL 执行结束后,SqlTableLookup 内存会被统一释放,最终并不会出现真正的内存泄漏。
obclient [oceanbase]> select * from __all_virtual_memory_info order by hold desc limit 10;
输出结果如下:
+-----------+--------------+----------+--------+------------------+-----------------+----------+--------+------------------+-------+--------------+--------------+---------+-------------+------------+
| tenant_id | svr_ip | svr_port | ctx_id | label | ctx_name | mod_type | mod_id | mod_name | zone | hold | used | count | alloc_count | free_count |
+-----------+--------------+----------+--------+------------------+-----------------+----------+--------+------------------+-------+--------------+--------------+---------+-------------+------------+
| 1001 | xx.xx.xx.xx | 2882 | 0 | SqlTableLookup | DEFAULT_CTX_ID | user | 0 | SqlTableLookup | zone1 | 251351794368 | 224659121504 | 6713541 | 0 | 0 |
| 1001 | xx.xx.xx.xx | 2882 | 0 | MysqlRequesReco | DEFAULT_CTX_ID | user | 0 | MysqlRequesReco | zone1 | 14364100608 | 14309995520 | 6813 | 0 | 0 |
| 1001 | xx.xx.xx.xx | 2882 | 0 | MysqlRequesReco | DEFAULT_CTX_ID | user | 0 | MysqlRequesReco | zone2 | 14336844288 | 14282839040 | 6800 | 0 | 0 |
| 1001 | xx.xx.xx.xxx | 2882 | 0 | MysqlRequesReco | DEFAULT_CTX_ID | user | 0 | MysqlRequesReco | zone3 | 14259268608 | 14205547520 | 6763 | 0 | 0 |
| 1001 | xx.xx.xx.xxx | 2882 | 1 | OB_MEMSTORE | MEMSTORE_CTX_ID | user | 0 | OB_MEMSTORE | zone3 | 12974008320 | 12971285600 | 6188 | 0 | 0 |
| 1001 | xx.xx.xx.xx | 2882 | 1 | OB_MEMSTORE | MEMSTORE_CTX_ID | user | 0 | OB_MEMSTORE | zone2 | 12946752000 | 12944035000 | 6175 | 0 | 0 |
| 1002 | xx.xx.xx.xx | 2882 | 1 | OB_MEMSTORE | MEMSTORE_CTX_ID | user | 0 | OB_MEMSTORE | zone2 | 11764247040 | 11761778200 | 5611 | 0 | 0 |
| 1002 | xx.xx.xx.xx | 2882 | 1 | OB_MEMSTORE | MEMSTORE_CTX_ID | user | 0 | OB_MEMSTORE | zone1 | 11214927360 | 11212573800 | 5349 | 0 | 0 |
| 1002 | xx.xx.xx.xxx | 2882 | 1 | OB_MEMSTORE | MEMSTORE_CTX_ID | user | 0 | OB_MEMSTORE | zone3 | 11204444160 | 11202092800 | 5344 | 0 | 0 |
| 1001 | xx.xx.xx.xx | 2882 | 0 | OB_KVSTORE_CACHE | DEFAULT_CTX_ID | user | 0 | OB_KVSTORE_CACHE | zone1 | 10778826240 | 10776194048 | 5141 | 0 | 0 |
+-----------+--------------+----------+--------+------------------+-----------------+----------+--------+------------------+-------+--------------+--------------+---------+-------------+------------+
10 rows in set (0.087 sec)
关键诊断信息
触发条件
生成了全局索引回表计划,并且需要回表的行数很多(千万行以上量级)或者回表涉及到的分区数较多(百个分区数以上)可能会触发该问题。
事前巡检
执行计划中包含 TABLE LOOKUP operator 并且 sql plan monitor 中,TableLookup 的 output 很大,可监控 memory info 中 SqlTableLookup 模块的内存使用是否有超过 1G 并且在快速增长现象。
事后诊断
observer.log 中关于 SqlTableLookup 模块的内存统计占比。
问题原因
内核缺陷,全局索引回表流程中未对创建任务使用的内存进行复用。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
影响的版本
OceanBase 数据库 V2.x 所有版本、OceanBase 数据库 V3.1 系列所有版本、OceanBase 数据库 V3.2.3 系列所有版本的老 SQL 引擎、OceanBase 数据库 V3.2.4 系列所有版本的老 SQL 引擎。
适用版本
OceanBase 数据库 V2.x、V3.x、V4.x 版本。
解决方法及规避方式
解决方法:
升级存在全局索引回表可能引起 TableLookup 内存剧烈膨胀问题的 OceanBase 数据库版本至 OceanBase 数据库 V4.x 及之后所有版本。
规避方式:
通过 outline 绑定计划,避免使用过滤性差的索引,在不是必须使用全局索引的场景里,建议将全局索引改为 local 索引。