【使用环境】调试环境
【ObServer】
【使用版本】3.1.5
【问题描述】
按照租户内存超限文档的介绍,检查 OB_MEMSTORE 模块内存泄露。
文档链接:https://www.oceanbase.com/docs/community-observer-cn-10000000000450197
操作步骤如下:
-
ALTER system SET leak_mod_to_check=‘OB_MEMSTORE’;
-
SELECT * FROM __all_virtual_mem_leak_checker_info ORDER BY alloc_count;
多次频繁查询,没有从 __all_virtual_mem_leak_checker_info 表中查询到所有信息。
经过调试代码,发现 ALTER system SET leak_mod_to_check=‘OB_MEMSTORE’ 使用的内存检查方式是 LABEL_CHECK。
但是只有通过 ObMallocAllocator::alloc() 方法申请内存,才会使用 LABEL_CHECK 方式进行内存泄露检查,而 OB_MEMSTORE 申请内存不会调用 ObMallocAllocator::alloc() 方法。
OB_MEMSTORE 会通过 ObTenantCtxAllocator::alloc() 方法申请内存,经过多级,会调用到 ObjectSet::alloc_object() 方法。
ObjectSet::alloc_object() 方法中会使用 CONTEXT_CHECK 方式进行内存泄露检查。
基于以上信息,有 2 个疑问:
-
问题一:OB_MEMSTORE 模块是否不能使用 LABEL_CHECK 方式进行内存泄露检查?
-
ObjectSet::alloc_object() 方法部分代码如下:
AObject* ObjectSet::alloc_object(const uint64_t size, const ObMemAttr& attr)
{
uint64_t alloc_size = size;
auto& leak_checker = common::ObMemLeakChecker::get_instance();
// ObTenantCtxAllocator::alloc() 经过多级调用 ObjectSet::alloc_object() 方法时
// mem_context_ 一直都是 null,check_leak 就为 false
bool check_leak = mem_context_ != nullptr && leak_checker.is_context_check() &&
leak_checker.get_static_id() == mem_context_->get_static_id();
if (OB_UNLIKELY(check_leak)) {
alloc_size += BT_BUF_LEN;
}
...
// 因为 check_leak = false,所以不会使用 CONTEXT_CHECK 方式进行内存泄露检查
// 也就是说 OB_MEMSTORE 模块也不会使用内存泄露检查
check_leak = check_leak && (leak_checker.is_wildcard() || leak_checker.label_match(*obj));
if (OB_UNLIKELY(check_leak)) {
common::lbt(&obj->data_[alloc_size - BT_BUF_LEN], BT_BUF_LEN);
}
...
}
问题二:OB_MEMSTORE 模块也无法使用 CONTEXT_CHECK 方式进行内存泄露检查?