diff --git a/src/observer/table/ob_table_session_pool.cpp b/src/observer/table/ob_table_session_pool.cpp index c446cc517..cb9d32692 100644 --- a/src/observer/table/ob_table_session_pool.cpp +++ b/src/observer/table/ob_table_session_pool.cpp @@ -16,6 +16,7 @@ using namespace oceanbase::share; using namespace oceanbase::common; +using namespace oceanbase::lib; namespace oceanbase { @@ -512,8 +513,11 @@ int ObTableApiSessPool::create_node_safe(ObTableApiCredential &credential, ObTab LOG_WARN("fail to alloc mem for ObTableApiSessNode", K(ret), K(sizeof(ObTableApiSessNode))); } else { tmp_node = new (buf) ObTableApiSessNode(credential); - tmp_node->last_active_ts_ = ObTimeUtility::current_time(); - node = tmp_node; + if (OB_FAIL(tmp_node->init())) { + LOG_WARN("fail to init session node", K(ret)); + } else { + node = tmp_node; + } } return ret; @@ -643,6 +647,30 @@ void ObTableApiSessNodeVal::give_back_to_free_list() } } +int ObTableApiSessNode::init() +{ + int ret = OB_SUCCESS; + + if (!is_inited_) { + MemoryContext tmp_mem_ctx = nullptr; + ContextParam param; + param.set_mem_attr(MTL_ID(), "TbSessNod", ObCtxIds::DEFAULT_CTX_ID) + .set_properties(lib::ALLOC_THREAD_SAFE); + if (OB_FAIL(ROOT_CONTEXT->CREATE_CONTEXT(tmp_mem_ctx, param))) { + LOG_WARN("fail to create mem context", K(ret)); + } else if (OB_ISNULL(tmp_mem_ctx)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null mem context ", K(ret)); + } else { + mem_ctx_ = tmp_mem_ctx; + last_active_ts_ = ObTimeUtility::fast_current_time(); + is_inited_ = true; + } + } + + return ret; +} + void ObTableApiSessNode::destroy() { int ret = OB_SUCCESS; @@ -653,34 +681,45 @@ void ObTableApiSessNode::destroy() ObTableApiSessNodeVal *rm_sess = free_list.remove(sess); if (OB_NOT_NULL(rm_sess)) { rm_sess->destroy(); + if (OB_NOT_NULL(mem_ctx_)) { + mem_ctx_->free(rm_sess); + } } } DLIST_FOREACH_REMOVESAFE(sess, used_list) { ObTableApiSessNodeVal *rm_sess = used_list.remove(sess); if (OB_NOT_NULL(rm_sess)) { rm_sess->destroy(); + if (OB_NOT_NULL(mem_ctx_)) { + mem_ctx_->free(rm_sess); + } } } - ObLockGuard alloc_guard(allocator_lock_); // lock allocator_ - allocator_.reset(); + if (OB_NOT_NULL(mem_ctx_)) { + DESTROY_CONTEXT(mem_ctx_); + } } int ObTableApiSessNode::remove_unused_sess() { int ret = OB_SUCCESS; - ObDList &free_list = sess_lists_.free_list_; - if (free_list.is_empty()) { - // do nothing + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("session node is not inited", K(ret)); } else { - ObLockGuard guard(sess_lists_.lock_); - DLIST_FOREACH_REMOVESAFE(sess, free_list) { - ObTableApiSessNodeVal *rm_sess = free_list.remove(sess); - if (OB_NOT_NULL(rm_sess)) { - rm_sess->~ObTableApiSessNodeVal(); - ObLockGuard alloc_guard(allocator_lock_); // lock allocator_ - allocator_.free(rm_sess); - rm_sess = nullptr; + ObDList &free_list = sess_lists_.free_list_; + if (free_list.is_empty()) { + // do nothing + } else { + ObLockGuard guard(sess_lists_.lock_); + DLIST_FOREACH_REMOVESAFE(sess, free_list) { + ObTableApiSessNodeVal *rm_sess = free_list.remove(sess); + if (OB_NOT_NULL(rm_sess) && OB_NOT_NULL(mem_ctx_)) { + rm_sess->~ObTableApiSessNodeVal(); + mem_ctx_->free(rm_sess); + rm_sess = nullptr; + } } } } @@ -696,19 +735,25 @@ int ObTableApiSessNode::remove_unused_sess() int ObTableApiSessNode::get_sess_node_val(ObTableApiSessNodeVal *&val) { int ret = OB_SUCCESS; - ObTableApiSessNodeVal *tmp_val = nullptr; - ObDList &free_list = sess_lists_.free_list_; - ObDList &used_list = sess_lists_.used_list_; - ObLockGuard guard(sess_lists_.lock_); - if (!free_list.is_empty()) { - tmp_val = free_list.remove_first(); - // move to used list - if (false == (used_list.add_last(tmp_val))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fail to add sess val to used list", K(ret), K(*tmp_val)); - } else { - val = tmp_val; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("session node is not inited", K(ret)); + } else { + ObTableApiSessNodeVal *tmp_val = nullptr; + ObDList &free_list = sess_lists_.free_list_; + ObDList &used_list = sess_lists_.used_list_; + + ObLockGuard guard(sess_lists_.lock_); + if (!free_list.is_empty()) { + tmp_val = free_list.remove_first(); + // move to used list + if (false == (used_list.add_last(tmp_val))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to add sess val to used list", K(ret), K(*tmp_val)); + } else { + val = tmp_val; + } } } @@ -724,30 +769,41 @@ int ObTableApiSessNode::get_sess_node_val(ObTableApiSessNodeVal *&val) int ObTableApiSessNode::extend_and_get_sess_val(ObTableApiSessGuard &guard) { int ret = OB_SUCCESS; - ObLockGuard alloc_guard(allocator_lock_); // lock allocator_ - void *buf = nullptr; - if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObTableApiSessNodeVal)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc mem for ObTableApiSessNodeVal", K(ret), K(sizeof(ObTableApiSessNodeVal))); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("session node is not inited", K(ret)); + } else if (OB_ISNULL(mem_ctx_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memory context is null", K(ret)); } else { - ObTableApiSessNodeVal *val = new (buf) ObTableApiSessNodeVal(this, credential_.tenant_id_); - if (OB_FAIL(val->init_sess_info())) { - LOG_WARN("fail to init sess info", K(ret), K(*val)); + ObTableApiSessNodeVal *val = nullptr; + void *buf = nullptr; + ObMemAttr attr(MTL_ID(), "TbSessNodVal", ObCtxIds::DEFAULT_CTX_ID); + if (OB_ISNULL(buf = mem_ctx_->allocf(sizeof(ObTableApiSessNodeVal), attr))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem for ObTableApiSessNodeVal", K(ret), K(sizeof(ObTableApiSessNodeVal))); } else { - ObLockGuard lock_guard(sess_lists_.lock_); - if (false == (sess_lists_.used_list_.add_last(val))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fail to add sess val to list", K(ret), K(*val)); + val = new (buf) ObTableApiSessNodeVal(this, credential_.tenant_id_); + if (OB_FAIL(val->init_sess_info())) { + LOG_WARN("fail to init sess info", K(ret), K(*val)); } else { - guard.sess_node_val_ = val; + ObLockGuard lock_guard(sess_lists_.lock_); + if (false == (sess_lists_.used_list_.add_last(val))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to add sess val to list", K(ret), K(*val)); + } else { + guard.sess_node_val_ = val; + } } } - } - if (OB_FAIL(ret) && OB_NOT_NULL(buf)) { - allocator_.free(buf); - buf = nullptr; + if (OB_FAIL(ret) && OB_NOT_NULL(val)) { + val->~ObTableApiSessNodeVal(); + mem_ctx_->free(val); + val = nullptr; + buf = nullptr; + } } return ret; diff --git a/src/observer/table/ob_table_session_pool.h b/src/observer/table/ob_table_session_pool.h index e619617cc..56554628a 100644 --- a/src/observer/table/ob_table_session_pool.h +++ b/src/observer/table/ob_table_session_pool.h @@ -164,14 +164,16 @@ friend class ObTableApiSessPool; friend class ObTableApiSessNodeVal; public: explicit ObTableApiSessNode(ObTableApiCredential &credential) - : allocator_("TbSessNode", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()), + : is_inited_(false), + mem_ctx_(nullptr), sess_lists_(), last_active_ts_(0), credential_(credential) { } ~ObTableApiSessNode() { destroy(); } - TO_STRING_KV(K_(sess_lists), + TO_STRING_KV(K_(is_inited), + K_(sess_lists), K_(last_active_ts), K_(credential)); class SessList @@ -189,6 +191,7 @@ public: DISALLOW_COPY_AND_ASSIGN(SessList); }; public: + int init(); void destroy(); bool is_empty() const { return sess_lists_.is_empty(); } int get_sess_node_val(ObTableApiSessNodeVal *&val); @@ -198,8 +201,8 @@ public: private: int extend_and_get_sess_val(ObTableApiSessGuard &guard); private: - common::ObArenaAllocator allocator_; - ObSpinLock allocator_lock_; // for lock allocator_ + bool is_inited_; + lib::MemoryContext mem_ctx_; SessList sess_lists_; int64_t last_active_ts_; ObTableApiCredential credential_; diff --git a/unittest/observer/table/test_table_sess_pool.cpp b/unittest/observer/table/test_table_sess_pool.cpp index 44c44178e..7f4276e95 100644 --- a/unittest/observer/table/test_table_sess_pool.cpp +++ b/unittest/observer/table/test_table_sess_pool.cpp @@ -132,9 +132,12 @@ TEST_F(TestTableSessPool, mgr_get_session) ASSERT_NE(0, node->last_active_ts_); // add mock val to node - ObTableApiSessNodeVal val(node, MTL_ID()); - val.is_inited_ = true; - ASSERT_EQ(true, node->sess_lists_.free_list_.add_last(&val)); + void *buf = nullptr; + ObMemAttr attr(MTL_ID(), "TbSessNodVal", ObCtxIds::DEFAULT_CTX_ID); + ASSERT_NE(nullptr, buf = node->mem_ctx_->allocf(sizeof(ObTableApiSessNodeVal), attr)); + ObTableApiSessNodeVal *val = new (buf) ObTableApiSessNodeVal(node, MTL_ID()); + val->is_inited_ = true; + ASSERT_EQ(true, node->sess_lists_.free_list_.add_last(val)); ObTableApiSessGuard guard; ASSERT_EQ(OB_SUCCESS, mgr->get_sess_info(*mock_cred_, guard)); @@ -216,9 +219,12 @@ TEST_F(TestTableSessPool, mgr_sess_recycle) // add mock val to node ObTableApiSessNode *node; ASSERT_EQ(OB_SUCCESS, mgr->pool_->get_sess_node(mock_cred_->hash_val_, node)); - ObTableApiSessNodeVal val(node, MTL_ID()); - val.is_inited_ = true; - ASSERT_EQ(true, node->sess_lists_.free_list_.add_last(&val)); + void *buf = nullptr; + ObMemAttr attr(MTL_ID(), "TbSessNodVal", ObCtxIds::DEFAULT_CTX_ID); + ASSERT_NE(nullptr, buf = node->mem_ctx_->allocf(sizeof(ObTableApiSessNodeVal), attr)); + ObTableApiSessNodeVal *val = new (buf) ObTableApiSessNodeVal(node, MTL_ID()); + val->is_inited_ = true; + ASSERT_EQ(true, node->sess_lists_.free_list_.add_last(val)); ObTableApiSessGuard guard; ASSERT_EQ(OB_SUCCESS, mgr->get_sess_info(*mock_cred_, guard));