Optimize memory release performance for logger

This commit is contained in:
obdev
2023-09-27 03:10:12 +00:00
committed by ob-robot
parent 56e5fe209a
commit 3c716958dd
11 changed files with 108 additions and 82 deletions

View File

@ -268,7 +268,7 @@ ob_set_subtarget(ob_malloc_object_list common_alloc
allocator/ob_allocator_v2.cpp
allocator/ob_block_alloc_mgr.cpp
allocator/ob_concurrent_fifo_allocator.cpp
allocator/ob_ctx_parallel_define.cpp
allocator/ob_ctx_define.cpp
allocator/ob_delay_free_allocator.cpp
allocator/ob_fifo_allocator.cpp
allocator/ob_hazard_ref.cpp

View File

@ -84,10 +84,10 @@ private:
};
template<typename t_lock>
class SetLockerForLogger : public ISetLocker
class SetLockerNoLog : public ISetLocker
{
public:
SetLockerForLogger(t_lock &mutex)
SetLockerNoLog(t_lock &mutex)
: mutex_(mutex), is_disable_(false) {}
void lock() override
{

View File

@ -43,7 +43,9 @@ public:
: resource_handle_(), ref_cnt_(0), tenant_id_(tenant_id),
ctx_id_(ctx_id), deleted_(false),
obj_mgr_(*this, tenant_id_, ctx_id_, INTACT_NORMAL_AOBJECT_SIZE,
common::ObCtxParallel::instance().parallel_of_ctx(ctx_id_), NULL),
CTX_ATTR(ctx_id).parallel_,
CTX_ATTR(ctx_id).enable_dirty_list_,
NULL),
idle_size_(0), head_chunk_(), chunk_cnt_(0),
chunk_freelist_mutex_(common::ObLatchIds::CHUNK_FREE_LIST_LOCK),
using_list_mutex_(common::ObLatchIds::CHUNK_USING_LIST_LOCK),
@ -58,7 +60,8 @@ public:
chunk_freelist_mutex_.enable_record_stat(false);
using_list_mutex_.enable_record_stat(false);
for (int i = 0; i < ObSubCtxIds::MAX_SUB_CTX_ID; ++i) {
new (obj_mgrs_ + i) ObjectMgr(*this, tenant_id_, ctx_id_, INTACT_MIDDLE_AOBJECT_SIZE, 4, &obj_mgr_);
new (obj_mgrs_ + i) ObjectMgr(*this, tenant_id_, ctx_id_, INTACT_MIDDLE_AOBJECT_SIZE,
4/*parallel*/, false/*enable_dirty_list*/, &obj_mgr_);
}
}
virtual ~ObTenantCtxAllocator()

View File

@ -11,6 +11,7 @@
*/
#include "object_mgr.h"
#include "lib/allocator/ob_ctx_define.h"
#include "lib/alloc/ob_malloc_allocator.h"
#include "lib/alloc/memory_sanity.h"
@ -18,12 +19,14 @@ using namespace oceanbase;
using namespace lib;
SubObjectMgr::SubObjectMgr(const bool for_logger, const int64_t tenant_id, const int64_t ctx_id,
const uint32_t ablock_size, IBlockMgr *blk_mgr)
const uint32_t ablock_size,
const bool enable_dirty_list,
IBlockMgr *blk_mgr)
: IBlockMgr(tenant_id, ctx_id), mutex_(common::ObLatchIds::ALLOC_OBJECT_LOCK),
normal_locker_(mutex_), logger_locker_(mutex_),
normal_locker_(mutex_), no_log_locker_(mutex_),
locker_(!for_logger ? static_cast<ISetLocker&>(normal_locker_) :
static_cast<ISetLocker&>(logger_locker_)),
bs_(), os_(NULL, ablock_size)
static_cast<ISetLocker&>(no_log_locker_)),
bs_(), os_(NULL, ablock_size, enable_dirty_list)
{
bs_.set_locker(&locker_);
os_.set_locker(&locker_);
@ -61,10 +64,12 @@ void SubObjectMgr::free_block(ABlock *block)
}
ObjectMgr::ObjectMgr(ObTenantCtxAllocator &allocator, uint64_t tenant_id, uint64_t ctx_id,
uint32_t ablock_size, int parallel, IBlockMgr *blk_mgr)
uint32_t ablock_size, int parallel, bool enable_dirty_list, IBlockMgr *blk_mgr)
: IBlockMgr(tenant_id, ctx_id), ta_(allocator),
ablock_size_(ablock_size), parallel_(parallel), blk_mgr_(blk_mgr), sub_cnt_(1),
root_mgr_(common::ObCtxIds::LOGGER_CTX_ID == ctx_id, tenant_id, ctx_id, ablock_size_, blk_mgr_),
ablock_size_(ablock_size), parallel_(parallel), enable_dirty_list_(enable_dirty_list),
blk_mgr_(blk_mgr), sub_cnt_(1),
root_mgr_(CTX_ATTR(ctx_id).enable_no_log_, tenant_id, ctx_id, ablock_size_,
enable_dirty_list, blk_mgr_),
last_wash_ts_(0), last_washed_size_(0)
{
root_mgr_.set_tenant_ctx_allocator(allocator);
@ -229,8 +234,8 @@ SubObjectMgr *ObjectMgr::create_sub_mgr()
root_mgr.unlock();
if (OB_NOT_NULL(obj)) {
SANITY_UNPOISON(obj->data_, obj->alloc_bytes_);
sub_mgr = new (obj->data_) SubObjectMgr(common::ObCtxIds::LOGGER_CTX_ID == ctx_id_, tenant_id_, ctx_id_,
ablock_size_, blk_mgr_);
sub_mgr = new (obj->data_) SubObjectMgr(CTX_ATTR(ctx_id_).enable_no_log_, tenant_id_, ctx_id_,
ablock_size_, enable_dirty_list_, blk_mgr_);
sub_mgr->set_tenant_ctx_allocator(ta_);
}
return sub_mgr;

View File

@ -13,7 +13,7 @@
#ifndef _OCEABASE_LIB_ALLOC_OBJECT_MGR_H_
#define _OCEABASE_LIB_ALLOC_OBJECT_MGR_H_
#include "lib/allocator/ob_ctx_parallel_define.h"
#include "lib/allocator/ob_ctx_define.h"
#include "lib/thread_local/ob_tsi_utils.h"
#include "lib/random/ob_random.h"
#include "lib/ob_abort.h"
@ -37,7 +37,8 @@ class SubObjectMgr : public IBlockMgr
friend class ObTenantCtxAllocator;
public:
SubObjectMgr(const bool for_logger, const int64_t tenant_id, const int64_t ctx_id,
const uint32_t ablock_size, IBlockMgr *blk_mgr);
const uint32_t ablock_size, const bool enable_dirty_list,
IBlockMgr *blk_mgr);
virtual ~SubObjectMgr() {}
OB_INLINE void set_tenant_ctx_allocator(ObTenantCtxAllocator &allocator)
{
@ -75,7 +76,7 @@ private:
lib::ObMutexV2 mutex_;
#endif
SetLocker<decltype(mutex_)> normal_locker_;
SetLockerForLogger<decltype(mutex_)> logger_locker_;
SetLockerNoLog<decltype(mutex_)> no_log_locker_;
ISetLocker &locker_;
BlockSet bs_;
ObjectSet os_;
@ -95,7 +96,8 @@ public:
};
public:
ObjectMgr(ObTenantCtxAllocator &allocator, uint64_t tenant_id, uint64_t ctx_id,
uint32_t ablock_size, int parallel, IBlockMgr *blk_mgr);
uint32_t ablock_size, int parallel, bool enable_dirty_list,
IBlockMgr *blk_mgr);
~ObjectMgr();
void reset();
@ -120,6 +122,7 @@ public:
ObTenantCtxAllocator &ta_;
uint32_t ablock_size_;
int parallel_;
bool enable_dirty_list_;
IBlockMgr *blk_mgr_;
int sub_cnt_;
SubObjectMgr root_mgr_;

View File

@ -34,14 +34,15 @@ void __attribute__((weak)) has_unfree_callback(char *info)
_OB_LOG_RET(ERROR, OB_ERROR, "HAS UNFREE PTR!!! %s", info);
}
ObjectSet::ObjectSet(__MemoryContext__ *mem_context, const uint32_t ablock_size)
ObjectSet::ObjectSet(__MemoryContext__ *mem_context, const uint32_t ablock_size,
const bool enable_dirty_list)
: mem_context_(mem_context), locker_(nullptr),
blk_mgr_(nullptr), blist_(NULL), last_remainder_(NULL),
bm_(NULL), free_lists_(NULL),
dirty_list_mutex_(common::ObLatchIds::ALLOC_OBJECT_LOCK), dirty_list_(nullptr), dirty_objs_(0),
alloc_bytes_(0), used_bytes_(0), hold_bytes_(0), allocs_(0),
normal_alloc_bytes_(0), normal_used_bytes_(0),
normal_hold_bytes_(0), ablock_size_(ablock_size),
normal_hold_bytes_(0), ablock_size_(ablock_size), enable_dirty_list_(enable_dirty_list),
cells_per_block_(AllocHelper::cells_per_block(ablock_size))
{}
@ -58,7 +59,7 @@ AObject *ObjectSet::alloc_object(
const int64_t ctx_id = blk_mgr_->get_ctx_id();
abort_unless(ctx_id == attr.ctx_id_);
if (OB_UNLIKELY(common::ObCtxIds::LIBEASY == ctx_id)) {
if (OB_UNLIKELY(enable_dirty_list_)) {
do_free_dirty_list();
}
@ -376,7 +377,7 @@ void ObjectSet::free_object(AObject *obj)
#endif
const int64_t ctx_id = blk_mgr_->get_ctx_id();
ObDisableDiagnoseGuard diagnose_disable_guard;
if (ctx_id == common::ObCtxIds::LIBEASY) {
if (OB_UNLIKELY(enable_dirty_list_)) {
if (locker_->trylock()) {
do_free_object(obj);
do_free_dirty_list();

View File

@ -45,7 +45,8 @@ class ObjectSet
public:
ObjectSet(__MemoryContext__ *mem_context=nullptr,
const uint32_t ablock_size=INTACT_NORMAL_AOBJECT_SIZE);
const uint32_t ablock_size=INTACT_NORMAL_AOBJECT_SIZE,
const bool enable_dirty_list=false);
~ObjectSet();
// main interfaces
@ -119,6 +120,7 @@ private:
uint64_t normal_hold_bytes_;
uint32_t ablock_size_;
bool enable_dirty_list_;
uint32_t cells_per_block_;
DISALLOW_COPY_AND_ASSIGN(ObjectSet);

View File

@ -10,15 +10,15 @@
* See the Mulan PubL v2 for more details.
*/
#include "lib/allocator/ob_ctx_parallel_define.h"
#include "lib/allocator/ob_ctx_define.h"
namespace oceanbase
{
namespace common
{
ObCtxParallel &ObCtxParallel::instance()
ObCtxAttrCenter &ObCtxAttrCenter::instance()
{
static ObCtxParallel instance;
static ObCtxAttrCenter instance;
return instance;
}
} // end of namespace common

View File

@ -0,0 +1,66 @@
/**
* 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.
*/
#ifndef OCEANBASE_COMMON_CTX_DEFINE_H_
#define OCEANBASE_COMMON_CTX_DEFINE_H_
#include "lib/allocator/ob_mod_define.h"
namespace oceanbase
{
namespace common
{
struct ObCtxAttr
{
const static int DEFAULT_CTX_PARALLEL = 8;
bool enable_dirty_list_ = false;
bool enable_no_log_ = false;
int parallel_ = DEFAULT_CTX_PARALLEL;
};
struct ObCtxAttrCenter
{
public:
ObCtxAttrCenter()
{
#define PARALLEL_DEF(name, parallel) ctx_attr_[ObCtxIds::name].parallel_ = parallel;
PARALLEL_DEF(DEFAULT_CTX_ID, 32)
PARALLEL_DEF(LIBEASY, 32)
PARALLEL_DEF(PLAN_CACHE_CTX_ID, 4)
PARALLEL_DEF(LOGGER_CTX_ID, 1)
#undef CTX_PARALLEL_DEF
#define ENABLE_DIRTY_LIST_DEF(name) ctx_attr_[ObCtxIds::name].enable_dirty_list_ = true;
ENABLE_DIRTY_LIST_DEF(LIBEASY)
ENABLE_DIRTY_LIST_DEF(LOGGER_CTX_ID)
#undef ENABLE_DIRTY_LIST_DEF
#define ENABLE_NO_LOG_DEF(name) ctx_attr_[ObCtxIds::name].enable_no_log_ = true;
ENABLE_NO_LOG_DEF(LOGGER_CTX_ID)
#undef ENABLE_NO_LOG_DEF
}
static ObCtxAttrCenter &instance();
ObCtxAttr attr_of_ctx(int64_t ctx_id) const
{
return ctx_attr_[ctx_id];
}
private:
ObCtxAttr ctx_attr_[ObCtxIds::MAX_CTX_ID];
};
#define CTX_ATTR(ctx_id) ObCtxAttrCenter::instance().attr_of_ctx(ctx_id)
}
}
#endif //OCEANBASE_COMMON_CTX_DEFINE_H_

View File

@ -1,54 +0,0 @@
/**
* 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.
*/
#ifndef OCEANBASE_COMMON_CTX_PARALLEL_DEFINE_H_
#define OCEANBASE_COMMON_CTX_PARALLEL_DEFINE_H_
#include "lib/allocator/ob_mod_define.h"
namespace oceanbase
{
namespace common
{
struct ObCtxParallel
{
public:
ObCtxParallel()
{
for (int64_t i = 0; i < ObCtxIds::MAX_CTX_ID; i++) {
parallel_[i] = DEFAULT_CTX_PARALLEL;
}
#define CTX_PARALLEL_DEF(name, parallel) parallel_[ObCtxIds::name] = parallel;
CTX_PARALLEL_DEF(DEFAULT_CTX_ID, 32)
CTX_PARALLEL_DEF(LIBEASY, 32)
CTX_PARALLEL_DEF(PLAN_CACHE_CTX_ID, 4)
CTX_PARALLEL_DEF(LOGGER_CTX_ID, 1)
#undef CTX_PARALLEL_DEF
}
static ObCtxParallel &instance();
int parallel_of_ctx(int64_t ctx_id) const
{
int p = 0;
if (ctx_id >= 0 && ctx_id < ObCtxIds::MAX_CTX_ID) {
p = parallel_[ctx_id];
}
return p;
}
private:
const static int DEFAULT_CTX_PARALLEL = 8;
int parallel_[ObCtxIds::MAX_CTX_ID];
};
}
}
#endif //OCEANBASE_COMMON_CTX_PARALLEL_DEFINE_H_

View File

@ -238,7 +238,7 @@ TEST_F(TestObjectMgr, TestSubObjectMgr)
abort_unless(ptr != MAP_FAILED);
int64_t tenant_id = OB_SERVER_TENANT_ID;
int64_t ctx_id = ObCtxIds::DEFAULT_CTX_ID;
SubObjectMgr som(false, tenant_id, ctx_id, INTACT_NORMAL_AOBJECT_SIZE, NULL);
SubObjectMgr som(false, tenant_id, ctx_id, INTACT_NORMAL_AOBJECT_SIZE, false, NULL);
ObMemAttr attr;
som.set_tenant_ctx_allocator(*ObMallocAllocator::get_instance()->get_tenant_ctx_allocator(
tenant_id, ctx_id).ref_allocator());