暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

oceanbase内存排查

张鹏 2024-07-15
321

oceanbase内存排查
【产品名称】
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_TRIGGER100,2) percent_trigger, round(MEM_LIMIT/1024/1024/1024,2) MEM_LIMIT_GB FROM gvmemstore WHERE tenant_id >1000 OR TENANT_ID=1 ORDER BY tenant_id,TOTAL_GB DESC; 错误码 4030 的出现可能有以下原因: 模块内存超限。 该问题的紧急应对措施是增加租户内存。问题解决之后需要分析原因,如果是因为未做限流引起,需要加上相应措施,然后回滚之前的租户内存修改。如果确实因为业务规模增长导致租户内存不足以支撑业务时,需要根据转储的频度设置合理的租户内存大小。如 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; 内存模块超限的判断标准是: module_sum 租户 min_memory 租户 MemStore。模块内存超限,可能需要先调整单独模块的内存,如 ob_sql_work_area_percentage 。如租户内存过小,也需要加租户内存。 PLANCACHE 命中率低于 90%。 OLTP 系统的 PLANCACHE 命中率应不低于 90%,运行下述语句查看 PLANCACHE 命中率。 obclient> SELECT hit_count,executions,(hit_count/executions) AS hit_ratio FROM vplan_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;
寻找是否有相似语句,如
in

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

allocate memory fail
等错误信息。
日志中包含
tenant_id
(租户编号)及
mod_id
(内存模块编号)信息,可以通过以下语句查询具体的内存模块信息。
obclient> select * from __all_virtual_memory_info where mod_id=xxx and tenant_id = xxx;如第一个常见内存问题中所述,模块内存超限,可能需要先调整单独模块的内存。如租户内存过小,也需要加租户内存
模块内存超限,可能需要先调整单独模块的内存。如租户内存过小,也需要加租户内存。

内存相关问题
更新时间:2024-04-24 14:53:01
编辑
分享
内存相关报错如下。
内部错误码 信息展示 报错含义
-4013 No memory or reach tenant memory limit 表示工作区内存不足。
-4030 Over tenant memory limits 表示租户内存不足。
租户内存不足
租户内存不足表示租户 MemTable 占用量达到设定阈值,导致应用 SQL 写入或者回放分配不出内存而报错。
可以通过视图 GVOB_MEMSTORE 确认租户 MemTable 的内存使用情况。 obclient> select * from GVOB_MEMSTORE limit 1\G
*************************** 1. row ***************************
SVR_IP: xx.xx.xx.xx
SVR_PORT: 2882
TENANT_ID: 1
ACTIVE_SPAN: 0
FREEZE_TRIGGER: 4294967250
FREEZE_CNT: 0
MEMSTORE_USED: 0
MEMSTORE_LIMIT: 8589934550
1 row in set (0.01 sec)
其中几个重要字段:
active_span:Active MemTable 内存的范围,用来估计 Active MemTable 内存使用量。
freeze_trigger:触发冻结的阈值。
memstore_used:MemTable 使用的内存总量,包括 Frozen MemTable 和 Active MemTable。
memstore_limit:MemTable 最大可用的租户内存。
基于以上字段:
memstore_used 接近或超过 memstore_limit 时,代表该租户 MemTable 内存写满。
active_span 大于 freeze_trigger 时,触发冻结。
MemTable 内存写满有两种原因:
MemTable 转储速度慢于写入速度:该场景可以自行恢复,即客户端报错之后,过一段时间内存自动释放。一旦出现首先应该尝试调大租户的内存规格。可以通过分析转储速度缓慢瓶颈、尝试提高转储速度,或者是减缓写入速度来减缓、解决这类问题。
MemTable 在转储后也无法释放:该场景为异常场景,需要联系技术支持进行介入诊断。
MemTable 内存未写满,但应用依然报错 4030 错误码时,表示其他模块挤占了 MemTable 部分的内存。常见的问题有两个:内存泄漏或者非 MemTable 的 mod 内存占用较大。需要隔离该节点并分析原因,重启 OBServer 后可恢复。
工作区内存不足
工作区内存,是指 SQL 排序等阻塞性算子使用的内存,通过租户系统变量 ob_sql_work_area_percentage 控制,默认值为 5%,即 工作区内存 = 租户内存 * ob_sql_work_area_percentage(默认 5%)。
如果请求并发量较大,且每个请求占用的工作区内存比较多,可能出现工作区内存不足的报错,经常出现的场景有 union、sort、group by 等。上述问题如果出现,可以通过适当调大系统变量来规避,例如:
obclient> set global ob_sql_work_area_percentage = 10;

租户内存写满
更新时间:2024-01-19 15:05:55
分享
租户内存(memstore)写满多数情况下是由突发的批量导入操作导致的,应急的操作主要以开启写入限速以及调整转储阈值等手段。
应急处理流程
租户内存写满一般表现为写入失败,报错No memory or reach tenant memory limit 或者 Over tenant memory limits。应急策略的优先级选择一般从高到低分别为:
1.增加租户内存配置。
建议直接在 OCP 上执行租户内存扩容操作,详情请参见 《OCP 使用指南》。通过命令行增加租户内存配置的操作如下:
使用 root 用户登录到数据库的 sys 租户。
执行以下 SQL 语句,确认当前租户使用的 unit_config。
注意
多个副本可能使用了不同的 resource_pool,您需要分别做出调整。
SELECT a.tenant_name,a.tenant_id,b.name unit_config,c.name pool_name,b.max_cpu,b.min_cpu,
round((b.max_memory/1024/1024/1024)) max_memory,round((b.min_memory/1024/1024/1024)) min_memory
FROM
__all_tenant a,
__all_unit_config b,
__all_resource_pool c
WHERE a.tenant_id=c.tenant_id
AND b.unit_config_id = c.unit_config_id
ORDER BY a.tenant_id desc;
执行修改 Unit 的 SQL 语句。
注意
截止 OceanBase 数据库 V3.2.x 版本,修改 resource unit 配置仅 CPU、Memory 配置是实际生效的,其他 IO 参数例如磁盘、iops 等都暂时无效,默认即可。
ALTER RESOURCE UNIT unit_config_name min_cpu=2,max_cpu=2, max_memory=‘4G’,min_memory=‘4G’, max_disk_size=‘500G’,max_iops=10000,min_iops=10000,max_session_num=10000;
2.调高转储线程数,加快转储,让内存尽快释放。
转储前数据会大量占据内存,快速转储结束能释放被占用的内存,minor_merge_concurrency 是控制并行转储线程数,您可以通过调高该参数值来达到快速释放内存的目的。该参数默认值为 0 ,表示系统会使用 OceanBase 数据库内核定义的使用 10 个线程作为通用转储工作线程数,修改该参数无需重启 OBServer 即刻生效。
注意
该参数调大的代价为 CPU 使用率升高,请根据具体情况决定是否开启。
具体方法如下:使用 root 用户登录到数据库的 sys 租户。
ALTER SYSTEM SET minor_merge_concurrency=x;
修改成功后,可以通过 SHOW PARAMETERS 语句查看是否修改成功。
SHOW PARAMETERS LIKE ‘minor_merge_concurrency’;
您还可以在 OCP 界面通过修改转储策略调高转储线程数,具体参见 修改转储配置。
3.当集群已经无法扩容租户总内存时,可调高租户 memstore 的比例,临时扩大可写入内存,并且调低转储阈值,让转储更快发生。
OceanBase中一个租户的 MemTable 内存的使用量达到配置项 freeze_trigger_percentage 所限制使用的百分比时,就会自动触发转储,转储后会释放占用的内存。该参数默认值为 70 ,表示当 memstore 使用率超过70%,就会触发转储。
另一个相关的参数是 memstore_limit_percentage,也就是租户内存中可用于 memstore 写入的比例,默认为 50%,意为租户使用 memstore 的内存占其总可用内存50%。例如一个内存配置为 10GB 的租户,memstore 可写入部分为 5G。该参数的取值范围为[1, 99],修改该参数无需重启 OBServer 即刻生效。
在应急场景下,可以调大 memstore_limit_percentage 的同时,调低freeze_trigger_percentage,达到临时扩容和尽快转储释放的目的。
具体方法如下:使用 root 用户登录到数据库的 sys 租户。
ALTER SYSTEM SET freeze_trigger_percentage=40;
ALTER SYSTEM SET memstore_limit_percentage=70;
4.开启写入限速,内存写入达到一定阈值 OB 会主动限制客户端导入速度。
writing_throttling_trigger_percentage 是租户级参数,该参数是调整写入速度的阈值,当 memstore 已使用的内存达到该阈值时,触发写入限速。该参数的默认值是 100,表示关闭写入限速机制。该参数的取值范围为 [0, 100],修改该参数无需重启 OBServer 即刻生效。另一个参数 writing_throttling_maximum_duration 表示触发限速后,剩余内存最多支持多长时间的写入时间,默认为1小时,该项一般不做修改。
ALTER SYSTEM SET writing_throttling_trigger_percentage = 80;
ALTER SYSTEM SET writing_throttling_maximum_duration = ‘1h’;
5.应用侧降级批处理任务。
当用户内存写满时,您可以考虑在应用侧降级对应租户的批处理任务。
租户内存写满
更新时间:2024-01-19 15:05:55

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论