常见内存问题 
===========================



1. `ERROR 4030 (HY000): OB-4030:Over tenant memory limits`。

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

   ```sql
   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;
   ```

   

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

   ```sql
   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;
   ```

   

   内存模块超限的判断标准是： `module_sum` \> 租户 `min_memory` \> 租户 MemStore。模块内存超限，可能需要先调整单独模块的内存，例如，调整 `ob_sql_work_area_percentage` 的值，如果租户内存过小，也需要增加租户内存。
   

2. PLANCACHE 命中率低于 90%。

   如果是 OLTP 系统 PLANCACHE 命中率应不低于 90%，运行下述语句查看 PLANCACHE 命中率：

   ```sql
   obclient> SELECT hit_count,executions,(hit_count/executions) as hit_ratio
   FROM v$plan_cache_plan_stat
   where (hit_count/executions) < 0.9;
   
   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;
   ```

   

   寻找是否有相似语句，例如 `in` 或 `not in` 后面的参数个数随机，导致大量浪费；如果不是上述情况，可能业务量或会话激增导致内存不足，需要调整租户内存大小。
   

3. 日志中有 `fail to alloc memory` 或 `allocate memory fail` 等错误信息。

   日志中会包含 `tenant_id` （租户编号）及 `mod_id` （内存模块编号）信息，可以通过以下语句查询具体的内存模块信息：

   ```sql
   obclient> SELECT * FROM __all_virtual_memory_info WHERE mod_id=xxx AND tenant_id = xxx
   ```

   

   从第一个常见内存问题中可知，如果模块内存超限，可能需要先调整单独模块的内存。如果租户内存过小，还需要增加租户内存。
   



