Files
oceanbase/src/clog/ob_batch_submit_ctx_mgr.cpp
gm 4a92b6d7df reformat source code
according to code styles, 'AccessModifierOffset' should be -2.
2021-06-17 10:40:36 +08:00

357 lines
11 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.
*/
#include "ob_batch_submit_ctx_mgr.h"
#include "lib/thread/ob_thread_name.h"
#include "common/ob_clock_generator.h"
#include "ob_batch_submit_ctx.h"
#include "ob_batch_submit_task.h"
#include "ob_log_define.h"
namespace oceanbase {
using namespace common;
namespace clog {
class ObBatchSubmitCtxMgr::RemoveIfFunctor {
public:
RemoveIfFunctor()
{}
~RemoveIfFunctor()
{}
public:
bool operator()(const transaction::ObTransID& trans_id, ObBatchSubmitCtx* ctx)
{
int tmp_ret = OB_SUCCESS;
if (!trans_id.is_valid() || OB_ISNULL(ctx)) {
tmp_ret = OB_INVALID_ARGUMENT;
CLOG_LOG(ERROR, "invalid arguments", K(tmp_ret), K(trans_id), KP(ctx));
} else if (OB_SUCCESS != (tmp_ret = ctx->try_split()) && OB_NO_NEED_BATCH_CTX != tmp_ret) {
CLOG_LOG(ERROR, "batch_submit_ctx try_split failed", K(tmp_ret), K(trans_id));
}
return OB_NO_NEED_BATCH_CTX == tmp_ret;
}
};
int ObBatchSubmitCtxMgr::init(
storage::ObPartitionService* partition_service, ObILogEngine* log_engine, const common::ObAddr& self)
{
int ret = OB_SUCCESS;
if (is_inited_) {
ret = OB_INIT_TWICE;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr inited twice", K(ret));
} else if (OB_ISNULL(partition_service) || OB_ISNULL(log_engine) || !self.is_valid()) {
ret = OB_INVALID_ARGUMENT;
CLOG_LOG(WARN, "invalid arguments", K(ret), KP(partition_service), KP(log_engine), K(self));
} else if (OB_FAIL(ctx_map_.init(ObModIds::OB_HASH_BUCKET_BATCH_SUBMIT_CTX))) {
CLOG_LOG(WARN, "batch submit ctx map init failed", K(ret));
} else {
partition_service_ = partition_service;
log_engine_ = log_engine;
self_ = self;
is_inited_ = true;
}
return ret;
}
int ObBatchSubmitCtxMgr::start()
{
int ret = OB_SUCCESS;
if (OB_FAIL(share::ObThreadPool::start())) {
CLOG_LOG(ERROR, "ObBatchSubmitCtxMgr thread failed to start", K(ret));
} else {
is_running_ = true;
}
CLOG_LOG(INFO, "ObBatchSubmitCtxMgr thread start finished", K(ret));
return ret;
}
void ObBatchSubmitCtxMgr::stop()
{
share::ObThreadPool::stop();
is_running_ = false;
CLOG_LOG(INFO, "ObBatchSubmitCtxMgr stop finished");
}
void ObBatchSubmitCtxMgr::wait()
{
share::ObThreadPool::wait();
CLOG_LOG(INFO, "ObBatchSubmitCtxMgr wait finished");
}
void ObBatchSubmitCtxMgr::reset()
{
is_inited_ = false;
is_running_ = false;
ctx_map_.reset();
partition_service_ = NULL;
log_engine_ = NULL;
self_.reset();
CLOG_LOG(INFO, "ObBatchSubmitCtxMgr reset");
}
void ObBatchSubmitCtxMgr::destroy()
{
is_inited_ = false;
stop();
wait();
ctx_map_.destroy();
partition_service_ = NULL;
log_engine_ = NULL;
CLOG_LOG(INFO, "ObBatchSubmitCtxMgr destroy");
}
int ObBatchSubmitCtxMgr::alloc_ctx(const transaction::ObTransID& trans_id,
const common::ObPartitionArray& partition_array, const ObLogInfoArray& log_info_array,
const ObLogPersistSizeArray& size_array, const ObISubmitLogCbArray& cb_array,
const common::ObMemberList& member_list, const int64_t replica_num, const common::ObAddr& leader,
common::ObILogAllocator* alloc_mgr, ObBatchSubmitCtx*& ctx)
{
int ret = OB_SUCCESS;
ObBatchSubmitCtx* tmp_ctx = NULL;
const int64_t partition_array_count = partition_array.count();
const int64_t log_info_array_count = log_info_array.count();
const int64_t log_persist_size_count = size_array.count();
const int64_t cb_array_count = cb_array.count();
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr is not inited", K(ret), K(trans_id));
} else if (!is_running_) {
ret = OB_NOT_RUNNING;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr is not running", K(ret), K(trans_id));
} else if (!trans_id.is_valid() || 0 == partition_array_count || partition_array_count != log_info_array_count ||
log_persist_size_count != log_info_array_count || partition_array_count != cb_array_count ||
!leader.is_valid() || leader != self_ || !member_list.is_valid() || replica_num <= 0 ||
NULL == alloc_mgr) {
ret = OB_INVALID_ARGUMENT;
CLOG_LOG(WARN,
"invalid arguments",
K(ret),
K(trans_id),
K(partition_array),
K(log_info_array),
K(size_array),
K(member_list),
K(replica_num),
K(leader),
K(self_),
KP(alloc_mgr));
} else if (OB_SUCCESS == (ret = ctx_map_.get(trans_id, tmp_ctx))) {
ret = OB_ERR_UNEXPECTED;
CLOG_LOG(ERROR, "when alloc_ctx, batch_ctx has already existed", K(ret));
} else if (OB_ENTRY_NOT_EXIST != ret) {
CLOG_LOG(ERROR, "get batch_submit_ctx error", K(ret), K(trans_id));
} else {
ret = OB_SUCCESS;
if (NULL == (tmp_ctx = ObBatchSubmitCtxFactory::alloc(alloc_mgr))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
CLOG_LOG(WARN, "alloc batch_submit_ctx failed", K(ret), K(trans_id));
} else if (OB_FAIL(tmp_ctx->init(trans_id,
partition_array,
log_info_array,
size_array,
cb_array,
member_list,
replica_num,
leader,
self_,
partition_service_,
log_engine_,
alloc_mgr))) {
CLOG_LOG(WARN,
"batch_submit_ctx init failed",
K(ret),
K(trans_id),
K(partition_array),
K(log_info_array),
K(size_array),
K(leader),
K(self_));
} else if (OB_FAIL(ctx_map_.insert_and_get(trans_id, tmp_ctx))) {
CLOG_LOG(WARN, "insert batch_submit_ctx error", K(ret), K(trans_id));
} else {
ctx = tmp_ctx;
}
if (OB_SUCCESS != ret && NULL != tmp_ctx) {
ObBatchSubmitCtxFactory::free(tmp_ctx);
tmp_ctx = NULL;
}
}
return ret;
}
int ObBatchSubmitCtxMgr::alloc_ctx(const transaction::ObTransID& trans_id,
const common::ObPartitionArray& partition_array, const ObLogInfoArray& log_info_array,
const ObLogPersistSizeArray& size_array, const common::ObAddr& leader, common::ObILogAllocator* alloc_mgr,
ObBatchSubmitCtx*& ctx)
{
int ret = OB_SUCCESS;
ObBatchSubmitCtx* tmp_ctx = NULL;
const int64_t partition_array_count = partition_array.count();
const int64_t log_info_array_count = log_info_array.count();
const int64_t log_persist_size_count = size_array.count();
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr is not inited", K(ret), K(trans_id));
} else if (!is_running_) {
ret = OB_NOT_RUNNING;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr is not running", K(ret), K(trans_id));
} else if (!trans_id.is_valid() || 0 == partition_array_count || partition_array_count != log_info_array_count ||
log_persist_size_count != log_info_array_count || !leader.is_valid() || leader == self_ ||
NULL == alloc_mgr) {
ret = OB_INVALID_ARGUMENT;
CLOG_LOG(WARN,
"invalid arguments",
K(ret),
K(trans_id),
K(partition_array),
K(log_info_array),
K(size_array),
K(leader),
K(self_),
KP(alloc_mgr));
} else if (OB_SUCCESS == (ret = ctx_map_.get(trans_id, tmp_ctx))) {
ret = OB_ERR_UNEXPECTED;
CLOG_LOG(ERROR, "when alloc_ctx, batch_ctx has already existed", K(ret));
} else if (OB_ENTRY_NOT_EXIST != ret) {
CLOG_LOG(ERROR, "get batch_submit_ctx error", K(ret), K(trans_id));
} else {
ret = OB_SUCCESS;
if (NULL == (tmp_ctx = ObBatchSubmitCtxFactory::alloc(alloc_mgr))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
CLOG_LOG(WARN, "alloc batch_submit_ctx failed", K(ret), K(trans_id));
} else if (OB_FAIL(tmp_ctx->init(trans_id,
partition_array,
log_info_array,
size_array,
leader,
self_,
partition_service_,
log_engine_,
alloc_mgr))) {
CLOG_LOG(WARN,
"batch_submit_ctx init failed",
K(ret),
K(trans_id),
K(partition_array),
K(log_info_array),
K(leader),
K(self_));
} else if (OB_FAIL(ctx_map_.insert_and_get(trans_id, tmp_ctx))) {
CLOG_LOG(WARN, "insert batch_submit_ctx error", K(ret), K(trans_id));
} else {
ctx = tmp_ctx;
}
if (OB_SUCCESS != ret && NULL != tmp_ctx) {
ObBatchSubmitCtxFactory::free(tmp_ctx);
tmp_ctx = NULL;
}
}
return ret;
}
int ObBatchSubmitCtxMgr::get_ctx(const transaction::ObTransID& trans_id, ObBatchSubmitCtx*& ctx)
{
int ret = OB_SUCCESS;
ObBatchSubmitCtx* tmp_ctx = NULL;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr is not inited", K(ret), K(trans_id));
} else if (!is_running_) {
ret = OB_NOT_RUNNING;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr is not running", K(ret), K(trans_id));
} else if (!trans_id.is_valid()) {
ret = OB_INVALID_ARGUMENT;
CLOG_LOG(WARN, "invalid arguments", K(ret), K(trans_id));
} else if (OB_FAIL(ctx_map_.get(trans_id, tmp_ctx))) {
CLOG_LOG(TRACE, "ctx_map_ get failed", K(ret), K(trans_id));
} else if (OB_ISNULL(tmp_ctx)) {
ret = OB_ERR_UNEXPECTED;
CLOG_LOG(WARN, "ctx is NULL", K(ret));
} else {
ctx = tmp_ctx;
}
return ret;
}
int ObBatchSubmitCtxMgr::revert_ctx(ObBatchSubmitCtx* ctx)
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr is not inited", K(ret));
} else if (!is_running_) {
ret = OB_NOT_RUNNING;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr is not running", K(ret));
} else if (OB_ISNULL(ctx)) {
ret = OB_INVALID_ARGUMENT;
CLOG_LOG(WARN, "invalid argument", K(ret));
} else {
ctx_map_.revert(ctx);
}
return ret;
}
int ObBatchSubmitCtxMgr::free_ctx(const transaction::ObTransID& trans_id)
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr is not inited", K(ret), K(trans_id));
} else if (!is_running_) {
ret = OB_NOT_RUNNING;
CLOG_LOG(WARN, "ObBatchSubmitCtxMgr is not running", K(ret), K(trans_id));
} else if (OB_FAIL(ctx_map_.del(trans_id))) {
// free_ctx is triggered by special op, failure is unexpected
CLOG_LOG(ERROR, "del batch_submit_ctx failed", K(ret), K(trans_id));
}
return ret;
}
void ObBatchSubmitCtxMgr::run1()
{
lib::set_thread_name("BatchSubmitCtx");
while (!has_set_stop()) {
int ret = OB_SUCCESS;
const int64_t begin_ts = common::ObClockGenerator::getClock();
RemoveIfFunctor fn;
if (OB_FAIL(ctx_map_.remove_if(fn))) {
CLOG_LOG(WARN, "ctx_map_ remove_if failed", K(ret));
}
const int64_t end_ts = common::ObClockGenerator::getClock();
const int32_t sleep_ts = static_cast<const int32_t>(LOOP_INTERVAL - (end_ts - begin_ts));
if (sleep_ts > 0) {
usleep(sleep_ts);
}
ObBatchSubmitCtxFactory::statistics();
ObBatchSubmitDiskTaskFactory::statistics();
}
}
} // namespace clog
} // namespace oceanbase