Co-authored-by: wangt1xiuyi <13547954130@163.com> Co-authored-by: yangqise7en <877793735@qq.com> Co-authored-by: Zach41 <zach_41@163.com>
257 lines
6.3 KiB
C++
257 lines
6.3 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#define USING_LOG_PREFIX STORAGE
|
|
|
|
#include "ob_compaction_memory_context.h"
|
|
#include "lib/oblog/ob_log_module.h"
|
|
#include "share/ob_force_print_log.h"
|
|
#include "share/ob_thread_mgr.h"
|
|
#include "lib/allocator/ob_mod_define.h"
|
|
#include "share/rc/ob_tenant_base.h"
|
|
#include "share/scheduler/ob_tenant_dag_scheduler.h"
|
|
#include "ob_tablet_merge_task.h"
|
|
|
|
|
|
namespace oceanbase
|
|
{
|
|
using namespace common;
|
|
using namespace storage;
|
|
using namespace lib;
|
|
|
|
namespace compaction
|
|
{
|
|
|
|
|
|
/*
|
|
* ================================================= ObLocalArena =================================================
|
|
*/
|
|
ObLocalArena::ObLocalArena(
|
|
const lib::ObLabel &label,
|
|
const int64_t page_size)
|
|
: ref_mem_ctx_(nullptr),
|
|
arena_(label, page_size, MTL_ID(), ObCtxIds::DEFAULT_CTX_ID),
|
|
hist_mem_hold_(0)
|
|
{
|
|
ObCompactionMemoryContext *mem_ctx = CURRENT_MEM_CTX();
|
|
if (nullptr != mem_ctx) {
|
|
bind_mem_ctx(*mem_ctx);
|
|
}
|
|
}
|
|
|
|
ObLocalArena::ObLocalArena(
|
|
ObCompactionMemoryContext &mem_ctx,
|
|
const lib::ObLabel &label,
|
|
const int64_t page_size)
|
|
: ref_mem_ctx_(nullptr),
|
|
arena_(label, page_size, MTL_ID(), ObCtxIds::DEFAULT_CTX_ID),
|
|
hist_mem_hold_(0)
|
|
{
|
|
bind_mem_ctx(mem_ctx);
|
|
}
|
|
|
|
void ObLocalArena::bind_mem_ctx(ObCompactionMemoryContext &mem_ctx)
|
|
{
|
|
if (NULL == ref_mem_ctx_) {
|
|
ref_mem_ctx_ = &mem_ctx;
|
|
}
|
|
arena_.set_ctx_id(ref_mem_ctx_->get_ctx_id());
|
|
}
|
|
|
|
ObLocalArena::~ObLocalArena()
|
|
{
|
|
reset();
|
|
ref_mem_ctx_ = nullptr;
|
|
}
|
|
|
|
void* ObLocalArena::alloc(const int64_t size)
|
|
{
|
|
void *buf = arena_.alloc(size);
|
|
if (OB_NOT_NULL(buf)) {
|
|
update_mem_monitor();
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
void* ObLocalArena::alloc(const int64_t size, const ObMemAttr &attr)
|
|
{
|
|
void *buf = arena_.alloc(size, attr);
|
|
if (OB_NOT_NULL(buf)) {
|
|
update_mem_monitor();
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
void ObLocalArena::reset()
|
|
{
|
|
arena_.reset();
|
|
update_mem_monitor();
|
|
}
|
|
|
|
void ObLocalArena::clear()
|
|
{
|
|
arena_.clear();
|
|
update_mem_monitor();
|
|
}
|
|
|
|
void ObLocalArena::update_mem_monitor()
|
|
{
|
|
ref_mem_ctx_ = nullptr == ref_mem_ctx_
|
|
? CURRENT_MEM_CTX()
|
|
: ref_mem_ctx_;
|
|
|
|
int64_t cur_mem_hold = arena_.total();
|
|
if (nullptr != ref_mem_ctx_ && hist_mem_hold_ != cur_mem_hold) {
|
|
if (cur_mem_hold > hist_mem_hold_) {
|
|
ref_mem_ctx_->inc_local_hold_mem(cur_mem_hold - hist_mem_hold_);
|
|
} else {
|
|
ref_mem_ctx_->inc_local_free_mem(hist_mem_hold_ - cur_mem_hold);
|
|
}
|
|
hist_mem_hold_ = cur_mem_hold;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ================================================= Mem Monitor Part =================================================
|
|
*/
|
|
ObCompactionMemMonitor::ObCompactionMemMonitor()
|
|
: buffer_hold_mem_(0),
|
|
buffer_free_mem_(0),
|
|
local_hold_mem_(0),
|
|
local_free_mem_(0)
|
|
{
|
|
}
|
|
|
|
int64_t ObCompactionMemMonitor::get_hold_mem() const
|
|
{
|
|
int64_t hold_mem = 0;
|
|
hold_mem += ATOMIC_LOAD(&buffer_hold_mem_);
|
|
hold_mem += ATOMIC_LOAD(&local_hold_mem_);
|
|
hold_mem -= ATOMIC_LOAD(&buffer_free_mem_);
|
|
hold_mem -= ATOMIC_LOAD(&local_free_mem_);
|
|
|
|
return MAX(hold_mem, 0);
|
|
}
|
|
|
|
|
|
/*
|
|
* ================================================= Memory Context Part =================================================
|
|
*/
|
|
ObCompactionMemoryContext::ObCompactionMemoryContext(
|
|
const ObTabletMergeDagParam ¶m,
|
|
common::ObArenaAllocator &allocator)
|
|
: arena_(allocator),
|
|
ctx_id_(ObCtxIds::DEFAULT_CTX_ID),
|
|
inner_arena_("SafeArena", OB_MALLOC_NORMAL_BLOCK_SIZE),
|
|
safe_arena_(inner_arena_),
|
|
free_lock_(),
|
|
free_alloc_(),
|
|
mem_monitor_(),
|
|
mem_peak_total_(0),
|
|
is_reserve_mode_(false)
|
|
{
|
|
inner_init(param);
|
|
}
|
|
|
|
ObCompactionMemoryContext::ObCompactionMemoryContext(
|
|
common::ObArenaAllocator &allocator)
|
|
: arena_(allocator),
|
|
ctx_id_(ObCtxIds::DEFAULT_CTX_ID),
|
|
inner_arena_("SafeArena", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID(), ctx_id_),
|
|
safe_arena_(inner_arena_),
|
|
free_lock_(),
|
|
free_alloc_("FreeAlloc", MTL_ID()),
|
|
mem_monitor_(),
|
|
mem_peak_total_(0),
|
|
is_reserve_mode_(false)
|
|
{
|
|
}
|
|
|
|
ObCompactionMemoryContext::~ObCompactionMemoryContext()
|
|
{
|
|
destroy();
|
|
}
|
|
|
|
void ObCompactionMemoryContext::destroy()
|
|
{
|
|
safe_arena_.clear();
|
|
inner_arena_.reset();
|
|
}
|
|
|
|
void ObCompactionMemoryContext::inner_init(const ObTabletMergeDagParam ¶m)
|
|
{
|
|
is_reserve_mode_ = param.is_reserve_mode_ && is_mini_merge(param.merge_type_);
|
|
ctx_id_ = is_reserve_mode_
|
|
? ObCtxIds::MERGE_RESERVE_CTX_ID
|
|
: ObCtxIds::MERGE_NORMAL_CTX_ID;
|
|
|
|
lib::ObMemAttr arena_attr(MTL_ID(), "MemCtx", ctx_id_);
|
|
lib::ObMemAttr free_attr(MTL_ID(), "FreeMemCtx", ctx_id_);
|
|
|
|
if (is_mini_merge(param.merge_type_)) {
|
|
arena_attr.label_ = "MiniSafeMemCtx";
|
|
free_attr.label_ = "MiniFreeMem";
|
|
} else if (is_major_merge_type(param.merge_type_)) {
|
|
arena_attr.label_ = "MajorSafeMemCtx";
|
|
free_attr.label_ = "MajorFreeMem";
|
|
} else if (is_minor_merge_type(param.merge_type_)) {
|
|
arena_attr.label_ = "MinorSafeMemCtx";
|
|
free_attr.label_ = "MinorFreeMem";
|
|
} else {
|
|
// not compaction ctx
|
|
ctx_id_ = ObCtxIds::DEFAULT_CTX_ID;
|
|
arena_attr.ctx_id_ = ctx_id_;
|
|
free_attr.ctx_id_ = ctx_id_;
|
|
}
|
|
|
|
|
|
inner_arena_.set_attr(arena_attr);
|
|
free_alloc_.set_attr(free_attr);
|
|
if (ObCtxIds::DEFAULT_CTX_ID != ctx_id_) {
|
|
SET_MEM_CTX(*this);
|
|
}
|
|
}
|
|
|
|
void* ObCompactionMemoryContext::local_alloc(const int64_t size)
|
|
{
|
|
void *buf = nullptr;
|
|
if (size > 0) {
|
|
ObSpinLockGuard guard(free_lock_);
|
|
buf = free_alloc_.alloc(size);
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
void ObCompactionMemoryContext::local_free(void *ptr)
|
|
{
|
|
if (OB_NOT_NULL(ptr)) {
|
|
ObSpinLockGuard guard(free_lock_);
|
|
free_alloc_.free(ptr);
|
|
}
|
|
}
|
|
|
|
void ObCompactionMemoryContext::mem_click()
|
|
{
|
|
int64_t mem_total = 0;
|
|
mem_total += arena_.total();
|
|
mem_total += safe_arena_.total();
|
|
mem_total += free_alloc_.total();
|
|
mem_total += mem_monitor_.get_hold_mem();
|
|
|
|
mem_peak_total_ = MAX(mem_peak_total_, mem_total);
|
|
}
|
|
|
|
|
|
} //compaction
|
|
} //oceanbase
|