OceanBase 数据库中错误代码 4013 与 4030 有什么区别?

【产品名称】

OceanBase 数据库中错误代码 4013 与 4030 均代表内存不足。本文介绍两种情况的差异。

【产品版本】

OceanBase 数据库所有版本

【问题描述】

错误码 4013

错误码 4013 的错误信息如下。

ERROR 4013 ( HY001 ): No memory or reach tenant memory limit

该错误码表示各个模块内存不足,例如 working area 不足。出现该问题的可能原因是编译和执行模块内存不足。此时 MemStore 并没有占满,仅仅是各个模块内存不足导致的报错。

OceanBase 数据库的内存管理方法禁止任何模块通过 glibc 库中的的 malloc 与 free 接口申请和释放内存。OceanBase 数据库的内存除了预留给 500 租户和 sys 租户之外,大部分预留给了普通租户,普通租户的内存限制是可以调节的。但是普通租户的内存限制了普通租户下的 Ctx 内存,而 Ctx 内存的是被多个 Mod 分配占用。因此,找到对应的 Mod 或者 Ctx 就可以确定申请内存失败的操作类型。

错误码 4030

错误码 4030 的错误信息如下。

ERROR 4030 ( HY000 ): Over tenant memory limits

该错误码表示 MemStore 内存不足,该错误通常发生在 INSERT、UPDATE、DELETE 语句及 table_scan 动作等 MemStore 操作上,此时错误的日志信息不是 ERROR 级别,而是 WARN 级别。

当 MemStore 内存超限时,需要检查数据写入是否过量或未做限流。当遇到大量写入且数据转储跟不上写入速度的时候就会报这种错误。运行下述语句查看内存状态:

obclient> SELECT /*+ READ_CONSISTENCY(WEAK),query_timeout(100000000) */ TENANT_ID,IP, round(ACTIVE/1024/1024/1024,2)ACTIVE_GB, round(TOTAL/1024/1024/1024,2) TOTAL_GB, round(FREEZE_TRIGGER/1024/1024/1024,2) FREEZE_TRIGGER_GB, round(TOTAL/FREEZE_TRIGGER*100,2) percent_trigger, round(MEM_LIMIT/1024/1024/1024,2) MEM_LIMIT_GB FROM gv$memstore WHERE tenant_id >1000 OR TENANT_ID=1 ORDER BY tenant_id,TOTAL_GB DESC;

错误码 4030 的出现可能有以下原因:

  1. 模块内存超限。
  2. 该问题的紧急应对措施是增加租户内存。问题解决之后需要分析原因,如果是因为未做限流引起,需要加上相应措施,然后回滚之前的租户内存修改。如果确实因为业务规模增长导致租户内存不足以支撑业务时,需要根据转储的频度设置合理的租户内存大小。如 MemStore 内存未超限,运行下述语句判断是哪个内存模块超限:

obclient> SELECT tenant_id,svr_ip,sum(hold) module_sum FROM __all_virtual_memory_info WHERE tenant_id>1000 AND hold<>0 AND mod_name NOT IN ( ‘OB_KVSTORE_CACHE’,‘OB_MEMSTORE’) GROUP BY tenant_id,svr_ip;

  1. 内存模块超限的判断标准是:

    module_sum

    租户

    min_memory

    • 租户 MemStore。模块内存超限,可能需要先调整单独模块的内存,如

    ob_sql_work_area_percentage

    。如租户内存过小,也需要加租户内存。

  2. PLANCACHE 命中率低于 90%。

  3. OLTP 系统的 PLANCACHE 命中率应不低于 90%,运行下述语句查看 PLANCACHE 命中率。

obclient> SELECT hit_count,executions,(hit_count/executions) AS hit_ratio FROM v$plan_cache_plan_stat WHERE (hit_count/executions) < 0.9; obclient> SELECT hit_count,executions,(hit_count/executions) AS hit_ratio FROM v$plan_cache_plan_stat WHERE (hit_count/executions) < 0.9 AND executions > 1000;

  1. 寻找是否有相似语句,如

    in

    not in

    后面的参数个数随机,导致大量浪费;如果不是上述情况,可能业务量或会话激增导致内存不足,需要调整租户内存大小。

  2. 日志中有

    fail to alloc memory

    allocate memory fail

    等错误信息。

  3. 日志中包含

    tenant_id

    (租户编号)及

    mod_id

    (内存模块编号)信息,可以通过以下语句查询具体的内存模块信息。

obclient> select * from __all_virtual_memory_info where mod_id=xxx and tenant_id = xxx;如第一个常见内存问题中所述,模块内存超限,可能需要先调整单独模块的内存。如租户内存过小,也需要加租户内存

  1. 模块内存超限,可能需要先调整单独模块的内存。如租户内存过小,也需要加租户内存。

OB 写测试内存报错建议先看:OB 内存分配概述 (qq.com) 。当租户内存有一定规模情况下(16G),通过参数调优和性能监控,是可以避免内存不足报错。